C++:如果抛出异常,那么超出范围的对象将被销毁
C++: If an exception is thrown, are objects that go out of scope destroyed?
通常情况下,它会在作用域结束时被销毁。。不过,如果抛出异常,我可以看到问题的发生。
是。
C++标准n3337
15异常处理
§15.2构造函数和析构函数
1) 当控件从抛出表达式传递到处理程序时,析构函数为自try块以来构造的所有自动对象调用已输入。自动对象按相反的顺序销毁他们的建设完成。
2) 任何存储持续时间的对象,其初始化或由异常终止的销毁将具有销毁函数为其完全构造的子对象的所有执行(不包括类并集的变体成员),即用于的子对象主建造师(12.6.2)已完成执行,以及析构函数尚未开始执行。类似地,如果对象的非委托构造函数已完成执行该对象的委托构造函数退出时出现异常将调用对象的析构函数。如果对象是在新的表达式,匹配的解除分配函数(3.7.4.2、5.3.4,12.5)(如果有的话)被调用以释放该对象所占用的存储器。
3) 为自动对象调用析构函数的过程在从try块到throw表达式的路径上构造的是称为"堆栈展开"。如果在堆栈期间调用了析构函数展开退出时出现异常,调用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
}
是的,任何范围绑定变量都将被销毁。
void work()
{
Foo a;
Foo* b = new Foo;
// ... later
// exception thrown
delete b;
}
在本例中,当堆栈展开时抛出异常时,会调用a
的析构函数,但b
指向的内存会泄漏,因为它永远无法到达delete
调用。这是RAII如此有帮助的众多原因之一。
是。当您离开一个作用域(无论是正常情况下还是通过异常情况)时,该作用域的本地对象将被销毁。这是RAII/SBRM发挥作用的基本事实。
相关文章:
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 超出范围时使用对象
- 如何访问超出其块范围的对象?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 对象超出范围/转让所有权
- 从函数返回范围视图时,带有std::span:中间对象所有权的C++Ranges-v3
- 读取互斥对象范围之外的volatile变量,而不是std::atomic
- 是否可以在C++ (C) 中使用全局范围对象(结构)?
- 基于范围的 for 循环将对象移动到另一个容器中?
- 对象超出范围后,引用成员设置为 0
- 哪个函数负责C++全局范围内的类对象初始化?
- 非常量对象的向量似乎在基于范围的 for 循环中被视为常量
- 如果一个对象是在本地创建的,并在C++中作为异常抛出,那么本地对象如何在其范围之外有效,即在 catch 块中?
- 什么是OOP中的对象范围
- 在C++中,指向对象的指针将指向对象范围之外的内容
- 抛出的对象范围
- C++:在对象范围外调用析构函数
- 如何根据多个参数查找容器中的对象范围
- 将对象范围扩展到if语句之外