当方法抛出异常时,方法范围的对象是否会被销毁?

时间:2013-06-12 08:47:36

标签: c++ exception-handling

void MyClass::method()
{
 SomeObject a;
 methodThatCanThrowException();
}

我希望捕获调用堆栈中更高的异常,而不是method() - 但在此示例中是否会调用SomeObject析构函数?

2 个答案:

答案 0 :(得分:4)

是。这就是RAII工作的原因。这就是例外工作的原因。否则他们不会。

完整标准报价:

  

15.2构造函数和析构函数[except.ctor]
    1. 当控件从throw-expression传递到处理程序时,将为输入try块后构造的所有自动对象调用析构函数。自动对象按照完成构造的相反顺序销毁     2. 任何存储持续时间的对象,其初始化或销毁由异常终止,将为其所有完全构造的子对象(不包括类似联合的类的变体成员)执行析构函数,即,对于主要构造函数(12.6.2)已完成执行且析构函数尚未开始执行的子对象。类似地,如果对象的非委托构造函数已完成执行,并且该对象的委托构造函数以异常退出,则将调用该对象的析构函数。如果对象是在new-expression中分配的,则调用匹配的释放函数(3.7.4.2,5.3.4,12.5)(如果有)以释放对象占用的存储空间。
    3. 为从try块到throw-expression的路径构造的自动对象调用析构函数的过程称为“堆栈展开”。如果在堆栈展开期间调用的析构函数以异常退出,则std调用:: terminate(15.5.1)。 [注意:因此,析构函数通常应该捕获异常,而不是让它们从析构函数中传播出来。 - 注意]

答案 1 :(得分:3)

是。它有时被称为stack unwinding 在堆栈中捕获异常通常是一个好主意。我已经看到很多代码在它无法做很多事情时会遇到异常。 只需确保SomeObject的析构函数不会抛出异常。