一、析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序
如果析构函数必须执行一个动作,而该动作可能会在失败时抛出异常,该怎么办?
示例:
class DBConnection{
public:
static DBConnection create(); //返回DBConnection对象
void close(); //关闭联机;失败则抛出异常。
};
为确保客户不忘记在DBConnection对象上调用close(),一个合理的想法是创建一个用来管理 DBConnection资源的class,并在其析构函数中调用close。
class DBConn{ //这个class用来管理DBConnection对象
public:
~DBConn(){ //确保数据库连接总是会被关闭
db.close();
}
}
private:
DBConnection db;
};
两种方法:
1.如果close抛出异常就结束程序。通常通过调用abort完成
DBConn::~DBConn()
{
try{ db.close();}
catch( ... ){
//制作运转记录,记下对close的调用失败
std::abort();
}
}
2.吞下因调用close而发生的异常
DBConn::~DBConn()
{
try{ db.close();}
catch( ... ){
//制作运转记录,记下对close的调用失败
//不调用std::abort(),直接吞下异常;
}
}
class DBConnection{
public:
static DBConnection create(); //返回DBConnection对象
void close(); //关闭联机;失败则抛出异常
};
class DBConn{ //这个class用来管理DBConnection对象
public:
void close() //供客户使用的新函数
{
db.close();
closed = true;
}
~DBConn()
{
if ( !close ) {
try{ //关闭连接(如果客户不那么做的话)
db.close();
}
catch( ... ){
//制作运转记录,记录下来并结束程序或吞下异常
....
}
}
private:
DBConnection db;
bool closed;
};