C++中构造函数和虚拟函数的微妙关系

构造函数和虚拟函数之间存在许多比较微妙的关系,比如构造函数不能是虚拟函数,构造函 数不能正常调用虚拟函数等等,本文将会讨论产生这些问题的原因。

构造函数为什么不能是虚拟函数

构造函数和析构函数在设计之初就是成对出现的,他们是一种对称关系:构造分配资源,析 构释放资源;构造用来初始化,析构用来清理。但是现在有一个点他们极不对称:

  • 析构通常是虚函数
  • 构造不能是虚函数

构造和析构的另一个不对称的地方是异常处理,构造函数中出错只能抛出异常,但是析 构函数中不允许抛出异常

通常声明成虚函数的析构函数

关于析构通常是虚函数的问题,在 《Effective C++》一书中有讨论,原因很简单:

class Base { // 基类公共资源 };
class Sub : public Base { // 子类自己的资源 };

为了能够进行多态的处理程序,我们需要通过基类指针指向子类的对象:

Base* base = new Sub;

那么问题来了,当我们调用

delete base;

的时候,假如 Base 没有把析构函数声明成虚函数,那么它会直接调用 Base 的析构函数( 这一点在编译的时候就已经确定了),那么 Sub 中分配

你可能感兴趣的:(C/C++,c++,java,开发语言)