绝不在构造/析构函数中使用虚函数
假设有一个class继承体系,在构造函数中调用了一个虚函数,如:
class A{public:A();virtual void dosomething();}A::A(){dosomething();}
class B:public A{public:virtual void dosomething();}
然后执行如下语句
B b;
无疑的,会有B的构造函数被调用,但首先A的构造函数会被调用,因为基类的构造函数总是先于派生类的构造函数被调用。
而此时在A的构造函数中被调用的dosomething()函数是A的版本,而不是被B覆盖的版本。因为在A的构造期间,b还是个基类对象,
不可能访问到B覆盖的版本,否则会导致不明确行为。比如B的dosomething()可能访问了某个派生成员,而在A的构造期间,那些派生成员
都还没被构造出来,这样就会导致不明确行为。
相同道理也适用于析构函数,一旦派生类析构函数开始执行,对象内的派生类成员变量就呈现为定义值,C++视他们不存在,进入基类虚构函数后对象就变成一个基类对象。
解决的办法是将那个函数声明为非虚的但需要参数。
由于你无法使用虚函数从基类向下调用,在构造期间,可以由派生类将必要的构造信息向上传递至基类构造函数加以弥补。

浙公网安备 33010602011771号