• 条款8: 不要让异常逃离析构函数


    举个例子:

    class DBConnection
    {
        public:
            ...
            static DBConnection create();
             
            void close();
    };//这个class负责数据库连接。
    //为了防止用户忘了close这个数据库连接,很容易想起来定义一个辅助类:
    class DBCon{
        public:
            ..
            ~DBCon(){dbc.close();}
        private:
        DBConnection dbc;
    }
    close如果调用成功的情况下,是没问题的。但是如果调用导致异常的话,DBConn的析构函数会传播这个异常,导致不可预料的后果。

    在析构函数中产生的异常通常按照两种方式来解决:

    异常产生就结束:(这样可以防止不明确的行为带来的伤害)

    DBConn::~DBConn()
    {
        try{
        dbc.close();
      }
    catch(...){ std:abort(); } }

    或者是吞下这个异常:

    DBConn::~DBConn()
    {
    try{ dbc.close(); }catch(...){ //制作运转记录,表明调用的失败 } }

    更好一点的解决方法是给DBConn自己也定义一个close函数,再用户不自己close的情况下在使用上面的做法,这样就给了用户一个处理异常的机会了:

    class DBConn{
        public:
            ...
            void close()
            {
                db.close();
                close = true;
            }
            ~DBConn()
            {
                if(close == false){
                    try{
                dbc.close();
             }
    catch(...){ std::abort(); } } } private: bool close; DBConnection dbc; };
    小结:析构函数绝对不应该吐出异常,如果一个被析构函数调用的函数可能会抛出异常,析构函数应该捕捉他们然后再吞下他们,像前面的程序做的那样。
    还有如果客户应该对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通的函数做这个操作,像上面的close那样。最后的析构函数中再做进一步的亡羊补牢
  • 相关阅读:
    打印当前系统内存使用情况
    swagger 相关
    乐观锁
    mybatis-plus
    kt connect
    flyway
    k8s mandatory.yaml & service-nodeport.yaml
    kubernetes的DNS解析,k8s的DNS解析,service DNS解析,在集群内部通过 Service 的域名形式进行互相通信
    k8s中引入外部服务,k8s中引入外部数据源
    docker 访问外部数据库
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4855019.html
Copyright © 2020-2023  润新知