《effective C++》中的条款14:确定基类有虚析构函数。也就是说,如果某个类要作为基类来使用,一般使用虚析构函数。看下面的例子:
class A{
public:
A(){
strA = new char[10];
strcpy(strA, "abc");
}
virtual ~A(){
cout<<"~A() " <<strA<<endl; delete []strA;
}
private:
char* strA;
};
class B: public A
{
public:
B(){
strB = new char[10];
strcpy(strB, "def");
}
~B(){
cout<<"~B() " <<strB<<endl;
delete []strB;
}
private:
char* strB;
};
测试:
A *p = new B; delete p;
代码的输出结果:
~A()
我们发现B类的析构函数没有调用,导致内存泄露。(因为动态编译,在运行时会检查有无派生类对象重载本函数,有则调用之。)
当我们可能通过基类指针删除派生类对象时,并且被析构的对象是有重要的析构函数的派生类的对象,就需要让基类的析构函数成为虚拟的。
当一个类不准备作为基类使用时,使析构函数为虚函数一般是个坏主意。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有类要作为基类来使用时,才把析构函数写成虚函数。