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

一. 内容

  1. 常见于工厂方法:一个 base class 指针指向 derived class 对象,而 base class 有个 non-virtual 函数。当删除base class 指针时,其结果未有定义,通常情况是对象的 derived 成分未被销毁,这样形成了一个诡异的局部销毁对象,这可是形成资源泄漏,败坏数据,浪费许多调试时间的绝佳途径。
  2. 消除这个问题的方法很简单,给 base class一个 virtual 析构函数。此后删除 derived class 对象就如你想要的那般。
  3. 为什么这样呢?virtual 关键字使得析构函数可以动态绑定,意味着当base class被赋值为 derived class,其上的析构函数动态更改为 derived class 上的析构函数,使得删除指针时可以真正调用 derived class 上的析构函数,不会出现只删除 base class 的情况。
  4. virtual 函数的实现,在于对象必须携带一些信息,来在运行期决定哪一个 virtual 函数被调用。这份信息通常是由一个 vtpr(virtual table pointer)指出。vtpr 指向一个由函数指针构成的数组,称为 vtbl(virtual table),每一个带有 virtual 函数的 class 都有一个相应的 vtbl,当对象调用某一 virtual 函数时,实际被调用的函数取决于该对象的 vptr所指的那个 vtbl,编译器会在其中寻找适当的函数指针,然后调用。
  5. virtual 函数的实现细节并不重要,关键需要代价,额外的 vtpr 可能使得对象不能进行高速缓存或者与其他语言对接,失去移植性。
  6. base class 不存在 virtual 析构函数时,使用多态的性质无疑是错误的,这会使得 derived class 在析构时出现第一点的情况,即 base class 指针指向 derived class 时析构异常。
  7. class 带有 pure virtual 函数时,称为 abstract class,即抽象类,也就是不能被实例化,如果你希望拥有 abstract class,可以使用析构函数作为 pure virtual 函数,因为 abstract class 常常用作不同实现,即多态,而多态需要virtual 析构函数,所以提供一份 pure virtual 析构函数即可。
  8. 析构函数的运作方式是,从最深层派生的那个 class 的析构函数最先被调用,然后每一个 base class 的析构函数被调用,意味着最高层的 pure virtual 析构函数也需要提供一份类外定义,否则链接器会报出异常。

二. 总结

  1. polymorphic(带多态性质)base class应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。
  2. Classes的设计目的如果不是作为base classes使用,或者不是为了具备多态性(polymorphically),就不应该声明virtuali析构函数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值