为多态基类声明virtual析构函数

书籍《Effective C++》中的条款7 读书笔记

条款7的内容,可以大致总结为下面几个问题:

问题1:什么是多态基类?

问题2:为什么要把多态基类的析构函数声明为virtual析构函数?

问题3:是不是应该把所有的类的析构函数声明为virtual函数?

下面来详细回答上面三个问题

问题1:什么是多态基类?

多态基类是由“多态”和“基类”两个词组成的,本质上就是一个类。这个类符合两个条件:

一是作为一个基类。基类的意思相信大家都懂的,就是一个类还派生了另外的类。

第二个条件是多态。所谓多态,就是指向基类对象的指针变量也可以指向派生类对象。

例如有如下一个类

class Aclass{

... ...

};

class Bclass :public Aclass{

... ...

};

Aclass *p=new Bclass;

问题2:为什么要把多态基类的析构函数声明为virtual析构函数?

因为C++明白指出,当derived class对象经由一个base指针删除(delete),而该base class带着一个

non-virtual析构函数,会发生一种情况:系统会只执行基类的析构函数,而不执行派生类的析构函数

这样子会造成一个诡异的“局部销毁”对象的现象,就是base class成分会被销毁,而drived class部分

则没有被销毁。

class Aclass{

public:

Aclass(){ }

~Aclass(){cout<<"Aclass destructor"<

};

class Bclass :public Aclass{

public:

Bclass(){ }

~Bclass(){cout<<"Bclass destructor"<

};

int main()

{

Aclass *p=new Bclass;

delete p;//删除指向drived对象的base指针

return 0;

}

运行结果为 :Aclass destructor

如果将多态基类的析构函数声明为虚析构函数,如virtual ~Bclass(){cout<<"Bclass destructor"<

其他部分不变,在运行程序,运行结果为:

Bclass destructor

Aclass destructor

问题3:是不是应该把所有的类的析构函数声明为virtual函数?

当一个class不企图当做base class,令其析构函数为virtual往往是一个馊主意。因为如果定义了一个虚函数,

为了能够确定程序运行时调用的是哪个函数,系统需要建立起一个虚函数表,这个表记录着函数调用的一些

信息,这样子更加了内存的使用。一般只将多态基类的析构函数定义为virtual析构函数。

你可能感兴趣的:(C++学习,多态,析构函数,虚函数)