C++在程序进行构造或析构期间,你绝不能调用虚函数,这是因为这样的调用并不会按你所期望的执行。C++中,如果在某个类的构造函数或者构造过程中调用了某个虚函数,该调用不会完全按照虚函数的多态性调用到其派生类的重写的函数,而只会调用到本类这个函数。下面是一个例子:
上面的例子稍微改变一下,比较隐蔽的一个例子:
从以上例子可以看出,某个类在构造过程中,绝不可能调用其派生类的函数,即使是虚函数。析构构成中同样。其原因,一种说法是在构造或者析构过程中,其派生类还没有创建或已经销毁,其虚函数表也不存在。所以无法调用。
在上面的例1中,如果class B中的f()定义为纯虚函数,则将是个更大的错误隐患,经测试在CB6和VC2003中编译都不会报错,运行时则会报运行时错误。如,VC报:pure virtual function call。
如果你曾经是一个 Java 或 C# 的程序员,并且在最近期望返回 C++ 的怀抱,那么请你格外的注意这一条,因为在这一问题上, C++ 与其他语言走的是完全不同的两条路线。在Java中这都是没有问题的。
我就深受Java的影响,在刚开始使用C++的时候,在一个项目中写下了类似于上面例2中的代码,是多个有继承关系的VCL form之间。不过奇怪的是,在CB的VCL form中,并没有出现上面两个例子中的问题,完全和在Java中一样,完全按照我原本的期望在基类form的构造函数中调用到了其派生类的虚函数。真是歪打正着,错误的写法,居然在CB的VCL中没有问题!这也让我没有及时发现C++在这个方面和其他语言的不同。知道今天才知道!原来其中还另有隐情!