通常它会在范围结束时被破坏..我可以看到如果抛出异常就会出现问题。
答案 0 :(得分:6)
是
C ++标准版n3337
§ 15.2构造函数和析构函数
1)当控件从throw-expression传递给处理程序时,析构函数 为自try块以来构造的所有自动对象调用 已输入。自动对象以相反的顺序销毁 完成他们的建设。
2)任何存储持续时间的对象,其初始化或 如果异常将具有析构函数,则终止销毁 执行所有的完全构建的子对象(不包括 类似联合类的变体成员),即子对象的变体成员 主要构造函数(12.6.2)已完成执行和 析构函数尚未开始执行。同样,如果 对象的非委托构造函数已完成执行并且a 委托该对象的构造函数以异常退出 将调用object的析构函数。如果对象是在一个中分配的 new-expression,匹配解除分配函数(3.7.4.2,5.3.4, 12.5),如果有的话,被调用来释放对象占用的存储空间。
3)为自动对象调用析构函数的过程 构造在从try块到throw-expression的路径上 称为“堆栈展开。”如果在堆栈期间调用析构函数 unwinding以异常退出,调用std :: terminate(15.5.1)。 [注意:所以析构函数通常应该捕获异常而不是让它们 它们从析构函数中传播出来。 - 结束说明]
示例:
SomeClass c; // declared before try{} so it is
// still valid in catch{} block
try {
SomeClass t;
throw;
} catch( ...) {
// t destroyed
// c valid
}
答案 1 :(得分:1)
是的,任何范围绑定变量都将被销毁。
void work()
{
Foo a;
Foo* b = new Foo;
// ... later
// exception thrown
delete b;
}
在这个示例中,当堆栈展开时抛出异常时会调用a
的析构函数,但b
指向的内存将被泄露,因为它永远不会到达delete
致电。这是RAII如此有用的众多原因之一。
答案 2 :(得分:0)
是。当您离开范围(无论是正常还是异常)时,该范围的本地对象将被销毁。这是使RAII / SBRM发挥作用的基本事实。