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

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

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

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

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

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

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

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

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

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

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

Base* base = new Sub;

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

delete base;

的时候,假如 Base 没有把析构函数声明成虚函数,那么它会直接调用 Base 的析构函数( 这一点在编译的时候就已经确定了),那么 Sub 中分配的子类资源得不到释放这就造成了 资源泄露。如果 Base 的析构函数是虚函数,那么它实际上会调用到子类的析构函数,而子 类的析构函数会自动调用基类的析构函数,最终使得基类和子类的资源都会得到释放。

Sub::~Sub() {
    this->
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值