在基类析构函数的声明前加上关键字virtual后,该析构函数就构成了虚析构函数,其派生类中的析构函数也随之成为虚析构函数,无需再加上关键字virtual。虚析构函数的权限都是public的。
虚析构函数的必要性:
析构函数一般用来释放申请的内存空间。如果析构函数不声明为虚拟的,则在程序执行的时候,可能造成内存的泄漏。
例子:
#include <iostream.h>
class A
{
public:
A(){cout << "A 构造函数/n";}
~A(){cout << "A 析构函数/n";}
virtual void use(){cout << "in A/n";}
};
class B:public A
{
public:
B(){cout << "B 构造函数/n";}
~B(){cout << "B 析构函数/n";}
virtual void use(){cout << "in B/n";}
};
class C:public B
{
public:
C(){cout << "C 构造函数/n";}
~C(){cout << "C 析构函数/n";}
virtual void use(){cout << "in C/n";}
};
void main()
{
A *obj;
obj = new C();
obj->use();
delete obj;
}
程序执行结果:
语句“obj = new C();”分别调用了类A、类B和类C的构造函数。但是“delete obj;”只调用了基类A的析构函数,从而造成了内存的泄漏。
引入虚析构函数
为了在调用基类析构函数的同时,通知并调用其他派生类的析构函数,需要引入虚拟析构函数。在定义基类析构函数的时候,只要加上关键字“virtual”就可以解决内存泄漏的问题。
#include <iostream.h>
class A
{
public:
A(){cout << "A 构造函数/n";}
virtual ~A(){cout << "A 析构函数/n";}
virtual void use(){cout << "in A/n";}
};
class B:public A
{
public:
B(){cout << "B 构造函数/n";}
~B(){cout << "B 析构函数/n";}
virtual void use(){cout << "in B/n";}
};
class C:public B
{
public:
C(){cout << "C 构造函数/n";}
~C(){cout << "C 析构函数/n";}
virtual void use(){cout << "in C/n";}
};
void main()
{
A *obj;
obj = new C();
obj->use();
delete obj;
}
程序执行结果:
当基类的析构函数被声明成虚函数后,就顺次调用了三个类的析构函数。
通常情况下,基类析构函数均定义为虚函数。
出自《C++程序设计教程》11.5节 (石志国等著)