基类析构函数是否为虚影响派生类析构函数的调用
class Base //基类
{
public:
~Base(); //此处将基类析构函数设置为常规析构
};
Base::~Base() //基类析构函数
{
cout << "Base Destruct" << endl;
}
class Derive:public Base //派生类
{
public:
~Derive();
};
Derive::~Derive() //派生类析构函数
{
cout << "Derive Destruct" << endl;
}
int main()
{
Base* p = new Derive; //基类指针指向派生类对象
delete p;
return 0;
}
可以看到基类析构函数不是虚函数,释放p只调用基类析构函数。
class Base //基类
{
public:
virtual~Base(); //将基类析构函数设置为虚函数,其他部分保持不变
//派生类的析构函数也自动成为析构函数
};
释放指针p,基类和派生类的析构函数都调用了。
总结:Base* p = new Derive;声明一个基类指针指向派生类,如果基类析构函数不是虚函数,则释放时将根据指针类型调用析构函数,所以Base类指针仅调用Base类析构函数;如果基类析构函数是虚函数,那么派生类的析构函数也自动成为虚函数,释放指针p时将根据对象类型调用析构函数,而指针虽然是基类指针,但是对象是派生类Derive,所以将基类析构函数设置为虚后释放指针时调用派生类析构函数,然后派生类析构函数自动调用基类析构函数,因此基类、派生类析构函数都被调用。
作用:当派生类中没有使用new或new[]申请新的空间时,基类的析构函数是否为虚并没有什么影响,但是如果派生类申请了空间,而基类析构不为虚,那么派生类对象的析构函数将无法被调用,也即派生类申请的空间无法得到释放,会导致内存问题,这就是为什么即使基类析构不做任何事情也要设置析构函数为虚函数的原因。
注意:创建派生类对象先调用基类构造函数,再调用派生类构造函数,释放时顺序相反。