条款11:禁止异常(exceptions)流出 destructor 之外
1️⃣ destructor 函数的调用时机
- 对象正常状态下被销毁,也就是当它离开了它的作用域(
scope
)或是被明确地删除。 - 当对象被
exception
处理机制销毁——也就是exception
传播过程中的(stack-unwinding)机制。
2️⃣ 理由一
有个
exception
正撰写你的destructor
。因为如果控制权基于exception
的因素离开destructor
,而此时正有另一个exception
处于作用状态,C++会调用terminate
函数。1
2
3
4
5
6
7
8
9
10class Session
{
public:
Session();
~Session();
...
private:
static void logCreation(Session* objAddr);
static void logDestruction(Session* objAddr);
};函数
logCreation
和logDestruction
分别用来记录对象的构造和析构。1
2
3
4Session::~Session()
{
logDestruction(this);
}- 如果
logDestruction
抛出一个异常exception
,会发生什么事情?- 首先,这个
exception
并不会被Session::destructor
捕捉,所以它会传播到destructor
的调用端。 - 其次,万一这个
destructor
本身是因其他某个exception
而被调用的,terminate
函数便会被自动调用,于是程序会直接走上了黄泉路。
- 首先,这个
- 如果
3️⃣ 理由二
如果
exception
从destructor
内抛出,而且没有在本地被捕捉到,那么就destructor
执行不完全。1
2
3
4
5
6
7
8
9
10
11Session::Session() // 为了简化,这个ctor不处理exceptions。
{
logCreation(this);
startTransaction(); // 开始一个数据库事务。
}
Session::~Session()
{
logDestruction(this);
endTransaction(); //结束一个数据库事务。
}如果
logDestruction
抛出一个exception
,于Session::Session
内创建的那个Transaction
绝对不会结束。或许在本例中,我们可以调换
destructor
中语句的位置,但是如果endTransaction
抛出异常,同样destructor
中不会执行完整。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 GYu的妙妙屋!