不要在类的构造函数与析构函数中调用虚函数 看如下代码:
class BASE
{
public:
BASE()
{
myPrint();
}
~BASE()
{
myRelease();
}
protected:
virtual void myPrint(){ cout << "Base" << endl; }
virtual void myRelease(){ cout << "Base Release" << endl; }
};
class DERIVED :public BASE
{
protected:
void myPrint(){ cout << "Derived" << endl; }
void myRelease(){ cout << "Derived Release" << endl; }
};
void main()
{
{
DERIVED d;
}
system("pause");
}
结果: 从运行结果可以看出,这不是我们想要的结果。
不要在构造函数中调用虚函数的原因
在概念上,构造函数的工作是为对象进行初始化。在构造函数完成之前,被构造的对象被认为“未完全生成”。当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数,那么此时派生类的构造函数并未执行,所调用的函数可能操作还没有被初始化的成员,这将导致灾难的发生。
在base构造期间,virtual函数绝不会下降到derived classes阶层。(在base构造期间,virtual函数不是虚函数)
在构造函数中调用一个虚函数,并不是通过虚函数表来调用的,编译器的做法是:在构造函数中调用的函数从所在类往根类回溯逐次找这个虚函数,找到哪个就调用哪个。这是静态方式调用。
同样的道理也使用于析构函数,一旦derived析构函数被调用,对象类的derived class 成员变量便呈现未定义值。
|