zoukankan      html  css  js  c++  java
  • Effective C++ 条款29 为"异常安全"而努力是值得的

    1. 当异常被抛出时,"异常安全"函数有两个条件:

        不泄露任何资源:从堆中申请的资源应该确保被释放

        不允许数据败坏:函数不能对数据修改到一半而抛出异常以致数据被破坏.

        解决"不泄露任何资源"很容易,只要使用资源管理类(如shared_ptr,见条款13)即可,"不允许数据败坏"是主要考虑的问题.

    2. 异常安全函数提供以下三种层次的保证:

        1) 基本保证:如果异常被抛出,"程序内任何事物仍然保持在有效状态下.没有任何对象或数据结构会因此而败坏."然而程序的现实状态很难预料:客户必须调用成员函数来确认对象的状态.

        2) 强烈保证:如果异常被抛出,程序状态不改变."如果函数成功,就是完全成功,如果函数失败,程序会回复到'调用函数之前'的状态".

        3) 不抛掷(nothrow)保证:程序绝不抛出异常且总是能够完成承诺的内容.

        以上三种层次的保证逐渐增强.

    3. 一般来说,实现不抛掷保证不太现实:1) 如果程序要保证nothrow,那么就要保证它所调用的函数也nothrow.2)任何使用动态内存的代码(如STL容器)都有可能抛出无法找到足够内存而产生的ban_alloc异常,因此,提供异常安全保证通常从基本保证和强烈保证中选择.

        要实现1中所提出的两个条件,一般有以下策略:

        1) 资源管理的使用以确保不泄露堆中资源.

        2) 对函数语句顺序的细致规划以阻止数据的败坏,这未必能完全避免数据败坏.

        3) 使用"copy and swap"策略:为打算修改的对象做出一份副本,然后在副本上进行修改,若函数抛出异常,只有副本的数据发生败坏,若修改成功执行,调用swap函数进行置换.这是解决数据败坏的有效途径.

        注意:途径3)虽然有效,但是仍然有以下限制:

        1)使用"copy and swap"策略构造临时对象,因此要付出额外的资源和效率负担.

        2)要使用swap函数,必须保证swap函数不抛出任何异常(见条款25).

        3)使用"copy and swap"策略并不能彻底根除数据败坏的可能性,如果函数内调用其它函数,会产生"连带影响".

     4. 异常安全符合短板原理:一个软件系统内只要有一个函数不符合异常安全性,整个软件系统就不具备异常安全性.

        

  • 相关阅读:
    Spring 整合 Redis
    Spring 整合 Redis
    C#,Java,MD5加密对等实现
    Java调用JavaWebService
    c#,Java aes加密
    Kettle环境变量配置
    Maven环境配置
    Win10,JDK8,tomact7.0.85配置
    ReverseEngineerCodeFirst 自定义模板
    Aspnet_Session
  • 原文地址:https://www.cnblogs.com/reasno/p/4771710.html
Copyright © 2011-2022 走看看