请教!

yuyunliuhen 2008-02-28 05:42:03
两个有什么不同?
template<typename T>
class CBase
{
static int i;
};
class A:public CBase<A>//继承的时候将本类的类型作为”参数“传入,这样做有啥好处?
{
};
class B:public CBase<A>
{
};


class CBase
{
static int i;
};
class A:public CBase
{
};
class B:public CBase{
};


这个算法的时间是多少?
template<int N,bool b>
class C;
template<int N>
class C<N,true>
{ enum{result=N+C<N-1,N-1%3==0>::result};
template<int N>
class C<N,false>{ enum{result=0+C<N-1,N-1%3>::result};
template<>
class C<0,true>{enum{result=0}};
mian()
{
printf("%d",C<1000,1000%3==0>::result);
}


两个面试题,各位把自己的想法说一下吧?谢谢!
...全文
71 7 打赏 收藏 举报
写回复
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuyunliuhen 2008-02-28
  • 打赏
  • 举报
回复
谢谢各位。
努力ING!
  • 打赏
  • 举报
回复

template<class T>
class Base1
{
public:
void func()
{
T* p = static_cast<T*>(this);
p->Doing();
}
};
class Base2
{
public:
void Doing()
{
}
void otherfunc()
{
}
};

class test:public Base1<test>,public Base2
{
public:
//void Doing(){};
};
int main()
{
test t;
t.func();
return 0;
}

假设test 提供 Base2提供了一些功能,Base1提供了一些功能。然后Base需要派生类提供一个Doing的函数。
而Base2中正好有,这样就可以直接调用到Base2的Doing,如果test对Base2提供的函数不满,直接自己写上一个Doing即可。
没有了虚函数,这种做法就是静态多态。
在ATL中运用的非常多。
hastings 2008-02-28
  • 打赏
  • 举报
回复

这个算法的时间是多少:1
baihacker 2008-02-28
  • 打赏
  • 举报
回复
第二个是编译时确定的...不需要花费运行时时间
p0303230 2008-02-28
  • 打赏
  • 举报
回复

帮顶
baihacker 2008-02-28
  • 打赏
  • 举报
回复

//编译时虚函数调用
//来源:
//原作 :Michael Dunn [英文原文]
//翻译 :Orbit(桔皮干了) [http://www.winmsg.com/cn/orbit.htm]
ATL-style 模板
即使你能够毫不费力地阅读C++的模板类代码,仍然有两件事可能会使你有些头晕,以下面这个类的定义为例:

class CMyWnd : public CWindowImpl<CMyWnd>
{
...
};
这样作是合法的,因为C++的语法解释说即使CMyWnd类只是被部分定义,类名CMyWnd已经被列入递归继承列表,是可以使用的。将类名作为模板类的参数是因为ATL要做另一件诡秘的事情,那就是编译期间的虚函数调用机制。

如果你想要了解它是如何工作地,请看下面的例子:

template <class T>
class B1
{
public:
void SayHi()
{
T* pT = static_cast<T*>(this); // HUH?? 我将在下面解释

pT->PrintClassName();
}
protected:
void PrintClassName() { cout << "This is B1"; }
};

class D1 : public B1<D1>
{
// No overridden functions at all
};

class D2 : public B1<D2>
{
protected:
void PrintClassName() { cout << "This is D2"; }
};

main()
{
D1 d1;
D2 d2;

d1.SayHi(); // prints "This is B1"
d2.SayHi(); // prints "This is D2"
}
这句代码static_cast<T*>(this) 就是窍门所在。它根据函数调用时的特殊处理将指向B1类型的指针this指派为D1或D2类型的指针,因为模板代码是在编译其间生成的,所以只要编译器生成正确的继承列表,这样指派就是安全的。(如果你写成:

class D3 : public B1<D2>
就会有麻烦) 之所以安全是因为this对象只可能是指向D1或D2(在某些情况下)类型的对象,不会是其他的东西。注意这很像C++的多态性(polymorphism),只是SayHi()方法不是虚函数。

要解释这是如何工作的,首先看对每个SayHi()函数的调用,在第一个函数调用,对象B1被指派为D1,所以代码被解释成:

void B1<D1>::SayHi()
{
D1* pT = static_cast<D1*>(this);

pT->PrintClassName();
}
由于D1没有重载PrintClassName(),所以查看基类B1,B1有PrintClassName(),所以B1的PrintClassName()被调用。

现在看第二个函数调用SayHi(),这一次对象被指派为D2类型,SayHi()被解释成:

void B1<D2>::SayHi()
{
D2* pT = static_cast<D2*>(this);

pT->PrintClassName();
}
这一次,D2含有PrintClassName()方法,所以D2的PrintClassName()方法被调用。

这种技术的有利之处在于:

不需要使用指向对象的指针。
节省内存,因为不需要虚函数表。
因为没有虚函数表所以不会发生在运行时调用空指针指向的虚函数。
所有的函数调用在编译时确定(译者加:区别于C++的虚函数机制使用的动态编连),有利于编译程序对代码的优化。
节省虚函数表在这个例子中看起来无足轻重(每个虚函数只有4个字节),但是设想一下如果有15个基类,每个类含有20个方法,加起来就相当可观了。


  • 打赏
  • 举报
回复
1
静态多态可以在Base中将this指针通过static_cast转化为派生类指针,调用派生类方法。
2
编译期计算。算法时间为0
发帖
C++ 语言

6.3w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
帖子事件
创建了帖子
2008-02-28 05:42
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下