虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象。
举例A* d = new B();(假定A是基类,B是从A继承而来的派生类),那么其(A类)析构函数必须是虚的,否则在delete d时,B类的析构函数将不会被调用,因而会产生内存泄漏和异常;
class Base
{
public:
Base(){}
virtual ~Base(){}
};
class Derived: public Base
{
public:
Derived(){};
~Derived(){};
}
void foo()
{
Base *pb;
pb = new Derived;
delete pb;
}
会发生动态绑定,它会先调用Derived的析构函数,然后是Base的析构函数。
如果不加virtual,delete pb只会执行Base的析构函数,而不是真正的Derived析构函数。
再看一个例子:
class A{
public:
int a;
A(){cout<<"A"<<endl;}
~A(){cout<<"~A"<<endl;}
};
class B{
public:
A* pA;
B(){pA= new A;cout<<"B"<<endl; }
virtual ~B(){delete pA;cout<<"~B"<<endl;}
//没有virtual时,不会调用C中析构
//有virtual时,会调用C中析构
};
class C:public B{
public:
C():B(){cout<<"C"<<endl;}
~C(){cout<<"~C"<<endl;}
};
int main(){
B *pB = new C;
delete pB;
return 0;
}
没有virtual时,A B C ~A ~B
参考:1.http://blog.csdn.net/Eric_Jo/article/details/4161480
2.http://www.cnblogs.com/chio/archive/2007/09/10/888260.html