zoukankan      html  css  js  c++  java
  • 条款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那样。最后的析构函数中再做进一步的亡羊补牢
  • 相关阅读:
    关于ThreadLocal的理解
    常用Linux软件安装
    Spring事务注解@Transactional失效的问题
    使用jackson转换xml格式数据进行响应
    创建简单web程序了解servlet
    JDBC
    StringBuild类
    Canlendar 日期类
    Java Date 时间类的使用
    QWeb
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4855019.html
Copyright © 2011-2022 走看看