Effective C++条款07:为多态基类声明virtual析构函数

显而易见,这个条款和多态的这个特性息息相关。多态的其中一个重要是通过我们在基类中的声明虚函数,子类进行重写(override)。那么在基类中,我们声明了虚函数或者纯虚函数,那么我们应该对应地就要有虚析构函数,但是往往我们会忽略这个问题,这就会导致严重的内存泄漏问题。

下面我们上代码:

class base  //这里的基类并没有声明虚析构函数
{
	public:
		base()
		{
			std::cout<<"creating base class!"<
class derived:public base  //继承基类的子类
 {
 	public:
 		derived()
		{
		 	std::cout<<	"creating derived class!"<
 int main()
 {
 	base *a = new derived();
 	a->test();
 	delete a;
 	return 0;
  } 

我们可以看到这里是声明一个父类指针指向了建立的子类对象。我们看一下运行结果:

Effective C++条款07:为多态基类声明virtual析构函数_第1张图片

我们可以看到,这里的析构函数只调用了基类的析构函数,这说明,派生类中的成分并没有被析构,这就会造成资源、内存的泄漏。

但我们将基类的析构函数改为虚析构函数:


class base
{
	public:
		base()
		{
			std::cout<<"creating base class!"<

我们可以看到结果如下:

Effective C++条款07:为多态基类声明virtual析构函数_第2张图片

显而易见,此时,析构时,基类和派生类的析构函数都被调用,程序按照我们的预期结束。

之所以会这样的原因如下:

原因是基类指针指向了派生类对象,而基类中的析构函数却是非virtual的,我们都知道,虚函数是动态绑定的基础。现在析构函数不是virtual的,因此不会发生动态绑定,而是静态绑定,指针的静态类型为基类指针,因此在delete时候只会调用基类的析构函数,而不会调用派生类的析构函数。这样,在派生类中申请的资源就不会得到释放,就会造成内存泄漏,这是相当危险的:如果系统中有大量的派生类对象被这样创建和销毁,就会有内存不断的泄漏,久而久之,系统就会因为缺少内存而崩溃。

 

需要记住的点:

1、polymorphic(带多态性质的)base class应该声明一个virtual析构函数。如果class带有任何virtual函数,他就应该拥有一个virtual析构函数。

2、classes的设计目的如果不是作为base classes使用,或者不是为了具备多态性质,就不应该声明virtual析构函数。

你可能感兴趣的:(C++)