构造函数和虚拟函数之间存在许多比较微妙的关系,比如构造函数不能是虚拟函数,构造函 数不能正常调用虚拟函数等等,本文将会讨论产生这些问题的原因。
构造函数为什么不能是虚拟函数
构造函数和析构函数在设计之初就是成对出现的,他们是一种对称关系:构造分配资源,析 构释放资源;构造用来初始化,析构用来清理。但是现在有一个点他们极不对称:
- 析构通常是虚函数
- 构造不能是虚函数
构造和析构的另一个不对称的地方是异常处理,构造函数中出错只能抛出异常,但是析 构函数中不允许抛出异常
通常声明成虚函数的析构函数
关于析构通常是虚函数的问题,在 《Effective C++》一书中有讨论,原因很简单:
class Base { // 基类公共资源 };
class Sub : public Base { // 子类自己的资源 };
为了能够进行多态的处理程序,我们需要通过基类指针指向子类的对象:
Base* base = new Sub;
那么问题来了,当我们调用
delete base;
的时候,假如 Base 没有把析构函数声明成虚函数,那么它会直接调用 Base 的析构函数( 这一点在编译的时候就已经确定了),那么 Sub 中分配的子类资源得不到释放这就造成了 资源泄露。如果 Base 的析构函数是虚函数,那么它实际上会调用到子类的析构函数,而子 类的析构函数会自动调用基类的析构函数,最终使得基类和子类的资源都会得到释放。
Sub::~Sub() {
this->

本文探讨了C++中构造函数不能声明为虚拟函数的原因,以及构造函数无法正常调用虚函数的问题。指出析构函数通常需要声明为虚函数以避免资源泄露。同时,提出通过工厂方法实现类似虚构造函数的功能。
最低0.47元/天 解锁文章
3085

被折叠的 条评论
为什么被折叠?



