effective c++ 条款08:别让异常逃离析构函数

记住:
析构函数不要抛出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,忽悠异常或者结束程序。
如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数执行该操作。

class DBConn {
public:
    ...
    ~DBConn()            //确保数据库连接总是被关闭
    {
        db.close();
    }
private:
    DBConnection db;
};

如果db.close()抛出异常,可能会造成麻烦。

解决办法

DBConn::~DBConn()
{
    try { db.close(); }
    catch (...) {
        //记录下close的调用失败
        std::abort();
    }
}

或者忽略失败

DBConn::~DBConn()
{
    try { db.close(); }
    catch (...) {
        //记录下close的调用失败
    }
}

比较好的方式是把close的责任从DBConn析构函数移到DBConn的客户手上。

class DBConn {
public:
    ...
    void close()
    {
        db.close();
        closed = true;
    }
    ~DBConn()        
    {
        if (!closed) {
            try {
                db.close();
            }
            catch (...) {
                //记录下close的调用失败
                ...
            }
        }
    }
private:
    DBConnection db;
    bool closed;
};

 

posted @ 2018-06-11 21:36  pfsi  阅读(137)  评论(0编辑  收藏  举报