您的位置:首页 > 其它

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

2014-06-01 23:49 211 查看
结论1:析构函数绝对不要吐了异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序。

C++并不禁止析构函数吐出异常,但不鼓励这样做,只要析构函数吐出异常,程序可能过早结束或出现不明确行为。

两种避免析构函数吐出异常的方法:

例如:

class DBConnection {//负责数据库连接的class
public:
static DBConnection create();//返回DBConnection对象
void close();//关闭联机,失败则抛出异常
};
class DBConn {//管理DBConnection对象的class
public:
~DBConn() {//确保数据库连接总被关闭
db.close();
}
private:
DBConnection db;
};


方法一:如果close抛出异常,直接结束程序,则需要修改DBConn的析构函数为

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


方法二:吞下因调用close而发生的异常

DBConn::~DBConn() {
try {db.close();}
catch(...) {
}
}


结论2:如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作。

例如:上述例子中的close()函数可由客户调用,让客户有一个机会得以处理”因该操作而发生的异常”。



class DBConn {
public:
void close() {
db.close(); //供客户调用的新函数
closed = true;
}
~DBConn(){
if (!closed) {
try { db.close() }
catch (...) { }
}
}
private:
DBConnection db;
bool closed;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: