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; };