• 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应该提供一个普通函数(而非在析构函数中)执行该操作.

        

  • 相关阅读:
    利用Hexo搭建个人博客-环境搭建篇
    Appium的安装-MAC平台
    alias指令:设置命令别名
    Android学习——第一个NDK程序
    Android学习——windows下搭建Cygwin环境
    Android学习——windows下搭建NDK_r9环境
    Win7&Ubuntu12.04 双系统引导问题
    Android学习第三天-签名常用命令
    Android学习第三天-打包常用命令
    Android学习第二天-android常用命令
  • 原文地址:https://www.cnblogs.com/reasno/p/4749763.html
Copyright © 2020-2023  润新知