码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-10-04 22:18:02      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:

举个例子:

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那样。最后的析构函数中再做进一步的亡羊补牢

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

标签:

原文地址:http://www.cnblogs.com/-wang-cheng/p/4855019.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!