在构造函数内部调用虚函数
在普通的成员函数中调用虚函数时仍然是在运行时解析虚函数调用,因为此时对象并不知道其是属于成员函数所在的类或者是派生类。但是在构造函数中,虚机制没有作用,只有“本地”的虚函数会被调用,有两个原因:
首先,在构造函数中你只能知道基类对象已经初始化,但不知道谁将继承你,若调用派生类中对应的虚成员函数,则其可能操作尚未初始化的成员;
其次,构造函数首先初始化VPTR,此表只能根据基类和当前类来初始化,其在对象的生命周期里将不变,除非还有其他类以此为基类。如果紧接着调用下一步的构造函数,则其将VPTR指向自己的VTABLE,如此向后,直到最后一层。当进行虚函数调用时,只能利用当前的VPTR去获得对应的虚函数。
析构函数中调用虚函数
和构造函数一样,析构函数中调用虚函数,只能调用本地版本,基本原理通构造函数一样,唯一的区别是对于构造函数,类型信息尚不完全,调用析构函数时知道类型信息,但对应的虚函数不再可用,已经析构了。
//: C15:VirtualsInDestructors.cpp
// Virtual calls inside destructors
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {
cout << "Base1()/n";
f();
}
virtual void f() { cout << "Base::f()/n"; }
};
class Derived : public Base {
public:
~Derived() { cout << "~Derived()/n"; }
void f() { cout << "Derived::f()/n"; }
};
int main() {
Base* bp = new Derived; // Upcast
delete bp;
} ///:~
运行结果:
~Derived()/n
Base1()/n
Base::f()/n