条款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的妙妙屋!
