《Effective C++》条款7:关于多态情况下virtual析构函数问题
对于析构函数是否virtual主要看是否实在多态的情境下;
对于基类来说,首先需要明确的是,不是所有的基类都已多态为目标而诞生,例如条款6中曾经提过关于赋值和符号赋值的做基类的问题;
对于多态性来说,我们时常使用一个指向基类的指针来进行虚函数的调用;
#include<iostream>
using namespace std;
class amov {
public:
virtual void vfun() {
cout << "base vfun" << endl;
}
virtual ~amov() {
cout << "base ~amov" << endl;
}
};
class damov :public amov {
public:
virtual void vfun() {
cout << "derived vfun" << endl;
}
~damov() {
cout << "derived ~amov" << endl;
}
};
int main() {
amov* da = new damov();
amov* ba = new amov();
da->vfun();
ba->vfun();
delete da;
delete ba;
system("pause");
return 0;
}
如上所示:运行可以很清楚的看到调用链;

对于虚函数继承之前讲过,不再赘述;
对于虚构函数,如果采用virtual形式,则派生类先调用按照继承链逐层调用之前的析构函数,先销毁自己的,在销毁基类部分成员;
所以这说明了在多态情况下如果不声明析构函数为虚函数,则会使得只能调用基类的析构函数,从而无法销毁自己作为派生类新定义的成员,造成内存泄漏和垃圾无法回收;
仍然值得注意的是,对于析构函数声明为虚函数一定要在多态情况下,非多态基类盲目继承会导致不可预测的后果,例如继承string类,由于STL string没有虚析构函数,会导致派生类无法释放自己的内存,导致内存泄露;
所以总结就是一句话:
多态才用虚析构函数,不用虚析构函数的类必定不是为了多态而存在的;

浙公网安备 33010602011771号