条款08:别让异常逃离析构函数
Prevent exceptions from leaving destructors.
当 vector v 被销毁,编译器会负责销毁数组中的每个元素。假设数组长度为10,当第一个元素被调用析构函数时出现异常,这会导致后面9个元素没有被销毁。
有两种方式可以解决这种问题:
第一种是捕获异常的话直接结束程序:
DBConn::~DBConn() {
try {
db.close(); // 释放资源;
} catch (...) {
... // 标记失败;
std::abort(); // 退出程序;
}
}
第二种是吞下异常:
DBConn::~DBConn() {
try {
db.close(); // 释放资源;
} catch (...) {
... // 标记失败,并吞下异常;
}
}
上述两种方式虽然可以解决析构函数中出现异常的问题,但是一个较佳的方式是重新设计接口,使得客户有机会对异常做出反应。例如将 close 的责任从 DBConn 析构函数转交到客户上:
void DBConn::close() {
db.close(); // 释放资源;
closed = true;
}
DBConn::~DBConn() {
if (!closed) { // 如果客户端未调用 close 函数,由析构函数负责释放资源;
try {
db.close();
} catch (...) {
... // 标记失败,并吞下异常;
}
}
}
Last updated
Was this helpful?