zoukankan      html  css  js  c++  java
  • Effective C++ 条款8 别让异常逃离析构函数

    1. 当异常发生时,如果异常发生在一个try块内部,程序就会跳出该try块,并逐层寻找匹配的catch,跳出try块的过程中,会销毁该try内创建的对象并调用析构函数,如果调用析构函数的过程中又发生异常,程序就会调用标准库terminate函数(terminate函数调用abort函数)结束执行,例如:

    class A{
    public:
        ...
        void func(){
            ...
        }
        ~A{
           func();
           ...
        }
    private:
        ...
    }
    View Code

    由于A类的析构函数需要调用func函数,而func函数极有可能抛出异常,这时就需要避免异常逃离析构函数.

    2. 方法一:在析构函数内设置try块,一旦发生异常,立即终止程序,例如:

    class A{
    public:
        ...
        void func(){
            ...
        }
        ~A{
            try{
                func();
            }
            catch(...){
                std::abort();
                制作运转记录,记下对func调用失败
            }
        }
    private:
        ...
    }
    View Code

    这样可以在func函数发生异常时避免异常从析构函数内释放出去.

        方法二:吞下func发生的异常,例如:

    class A{
    public:
        ...
        void func(){
            ...
        }
        ~A{
            try{
                func();
            }
            catch(...){
                制作运转记录,记下对func调用失败
            }
        }
    private:
        ...
    }
    View Code

        方法三:前两者都无法对"导致func抛出异常"做出什么反应,另一个方法是避免func()在析构函数内执行,由客户来调用func函数,为避免客户忘记执行,需设立flag标记客户是否调用,如果客户没有调用,在析构函数内调用该函数:

    class A{
    public:
        ...
        void func(){
           flagg=true;
            ...
        }
        ~A{
            if(!flagg){
                try{
                    tmp.func();
                }
                catch(...){
                    std::abort();
                    制作运转记录,记下对func调用失败
                }
            }
        }
    private:
        ...
        bool flagg;
    }
    View Code

    这样把调用func的责任从A类的析构函数转移到客户,从而给客户一个“提前处理异常”的机会.

    3. 总结:

        1). 析构函数绝对不要吐出异常.如果一个被析构函数调用的函数可能吐出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或终止程序.

        2). 如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作.

        

  • 相关阅读:
    markdown with vim
    递归
    类 sizeof
    cppcheck工具
    c++ explicit的含义和用法
    pca主成分分析
    string的使用
    linux的shell进化简史
    adb shell 无法启动 (insufficient permissions for device)
    c++ 四种转换的意思
  • 原文地址:https://www.cnblogs.com/reasno/p/4749763.html
Copyright © 2011-2022 走看看