Effective C++之二十九

      要点:争取写异常安全的代码。

      Meyers通过PrettyMenu::changeBackground的例子,指出异常发生时可能发生的问题:

      1) Mutex的资源泄漏

      2) 没有new成功就改变了imageChanges

      3) bgImage指针状态错误,指向已删除的内存。

      从而引出异常安全函数的三种保证:

      1) 基本保证(the basic guarantee):确保异常发生时,程序保持在正确的状态(但是不一定是可预知的状态)。

      2) 强保证(the strong guarantee):确保异常发生时,程序的状态没有改变。

      3) 不抛出异常保证(the nothrown guarantee):确保不会抛出异

      Meyer特别指出,定义函数时如果其异常规格是没有异常,并不说明该函数不抛出异常,而是当异常发生时将调用unexpected函数。函数异常安全的保证是有函数实现决定的,而不是函数定义。

      要提供不抛出异常保证很困难,例如任何用到动态内存管理代码都可能抛出bad_alloc异常。尽可能提供不抛出异常保证,对大多数函数需在基本和强保证间选择。

      接着Meyers采用RAII、智能指针以及调换++语句顺序,将例子代码差不多达到了异常安全的强保证。之所以是差不多,是因为imgSrc流的状态发生了改变,所以不能提供强保证。

 

       Meyers提出通过“copy and swap”策略实现强保证的方法。原理很简单:先复制,修改复制的对象,最后交换。通常,需要将所有数据放入实现类,原对象中保存实现对象的指针,也就是通常所说的pimpl惯用法(参见条款31)。

      采用copy and swap策略很好地实现了对象“全部或没有”状态修改,但是它并不能确保整个函数是异常安全强保证的。Meyers举了调用f1和f2的例子,即使f1和f2都是强保证的,整个函数也不是强保证的。问题出在副作用,如果只是改变局部状态,确保强保证相对容易。如果有副作用,例如写了数据库,那就无法确保强保证。另外一个问题就是效率,每次修改都要复制对象。

      如果无法提供强保证,就需要提供基本保证。一般的,函数异常安全保证不会高于它调用的最弱保证。

      新写或修改代码时,应该虑如何使它变得异常安全。从使用对象管理资源开始,确保没有资源泄漏;然后确定提供什么异常安全保证;只有在使用遗留代码没有办法时才满足于无保证。函数的异常安全性应该是接口的有机部分。

 

      总结:

      - 记住基本、强和不抛出异常三类保证

      - copy and swap是实现强保证的策略,但是实现强保证并不是对所有函数都现实

      - 一般的,函数异常安全保证不会高于它调用的最弱保证。 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值