读Effective C++ 条歀09:绝不在构造和析构过程中调用虚函数(Never call virtual functions during construction or destruction)
首先,我们用一句在程序员中比较流行的话作为本文的开篇:如果你在基类的构造函数中调用虚函数,那么在基类构造期间,虚函数的行为像一个“实”函数。
在派生类对象的基类部分构造期间,对象的类型是base class,而不是derived class。这时,不只是虚函数会被编译器解析至基类型,就连RTTI中的typeid和dynamic_cast也会把对象视为基类型。C++标准和编译器这样做的原因其实很简单:在派生类对象的基类部分构造期间,派生类的专属成分尚未被初始化,所以面对它们,最安全的做法就是视它们不存在。派生类对象在自身的构造函数开始执行前,不会被作为一个派生类对象,而是被看作一个基类对象。
对于析构函数,也同样适用。一旦派生类的析构函数执行完毕,派生类对象中的派生类特有的成员变量变呈现未定义状态,所以此时,C++编译器视它们如无物,即:进入到基类的析构函数中后,就把派生类对象视为一个基类对象,此时,任何虚函数、typeid和dynamic_cast等等也这么看待它。
C++ primer中说,如果在构造函数或析构函数中调用虚函数,则运行的是构造函数或析构函数自身类型所定义的版本。这句话表达的有歧义,不过指的也是上面文字所说的意思。即:在派生类对象的基类部分构造期间,就把派生类