原文引自《C++ Prime》中文版P497:
构造派生类对象时首先运行基类构造函数初始化对象的基类部分。在执行基类构造函数时,对象的派生类部分是未初始化的。实际上,此时对象还不是一个派生类对象。
撤销派生类对象时,首先撤销它的派生类部分,然后按照与构造顺序的逆序撤销它的基类部分。
在这两种情况下,运行构造函数或析构函数的时候,对象都是不完整的。为了适应这种不完整,编译器将对象的类型视为在构造或析构期间发生了变化。在基类构造函数或析构函数中,将派生类对象当作基类类型对象对待。
示例:
class A {
A() { foo(); }
virtual ~A() { foo(); }
virtual void foo() { cout << "父类调用" << endl; }
void bar() { foo(); }
};
class B :public A {
virtual void foo() { cout << "子类调用" << endl; }
};
int main(){
B b;
b.bar();
}
输出:
C++不能将构造函数声明为虚函数
构造函数用来创建一个新的对象,而虚函数的运行是建立在对象的基础上,在构造函数执行时,对象尚未形成,所以不能将构造函数定义为虚函数。
可以将析构函数声明为虚函数防止内存泄漏
delete一个基类指针p时,如果析构函数为虚函数,则根据对象类型去析构对象。当p指向子类时先调用子类析构函数,再调用基类构造函数。
如果析构函数非虚,则只会根据指针类型调用基类析构函数,造成内存泄漏。
参考:
https://blog.csdn.net/weixin_30342827/article/details/95279077