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

C++不反对但也不鼓励在析构函数中吐出异常。

 

假设有一个负责连接数据库资源的class:

class DBConnection {

public:

...

static DBConnection create();

void close();

};

然后有一个负责DBConnection资源管理的class:

class DBConn { public: ... ~DBConn() { db.close(); } private: DBConnection db; };

然后有这样一句调用情况:

DBConn dbc(DBConnection::create()); //开启一个区块,建立 //DBConnection对象,并 //交给DBConn对象管理。 //通过DBConn接口使用 //DBConnection对象。在区块 //结束点,DBConn对象被销毁 //自动调用DBConnection对象 //调用close()

只要close调用成功,那就没问题。但是如果调用失败,DBConn函数就会抛出异常,造成问题。形成不明确的操作。

有两个不是很好的方法可以避免该问题:

1.在出现异常的是立马结束程序:

DBConn::~DBConn() { try{db.close();} catch(...) { //记录,这里出现异常拉!!!close()调用失败拉!!! std::abort(); //掐死程序 } }

2.忍气吞声,吞下异常

DBConn::~DBConn() { try { db.close(); } catch(...) { 记录,这里出现异常拉!!!close()调用失败拉!!! } }

一个比较好的方法是重新设计DBConn的接口,使客户机会对可能出现的问题作出反应:

class DBConn{ public: ... void close() { db.close(); closed = true; } ~DBConn() { if(!closed) { try { db.close(); } catch { 记录,这里出现异常拉!!!close()调用失败拉!!! } } } private: DBConnection db; bool closed; };

DBConn自己提供了一个close函数,所以客户有一个机会得以处理”因该操作而发生异常“。并且追踪管理之DBConnection是否已被关闭。并在答案为否的情况下由析构函数关闭。

 

 

析构函数绝对不要吐出异常,如果一个析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们或者结束程序。

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值