c++ - 在 C++ 中抛出后会调用析构函数吗?

标签 c++ exception-handling try-catch raii

我运行了一个示例程序,确实调用了堆栈分配对象的析构函数,但这是否由标准保证?

最佳答案

是的,保证(只要捕获到异常),直到调用析构函数的顺序:

C++11 15.2 Constructors and destructors [except.ctor]

1 As control passes from a throw-expression to a handler, destructors are invoked for all automatic objects constructed since the try block was entered. The automatic objects are destroyed in the reverse order of the completion of their construction.

此外,如果在对象构造过程中抛出异常,则保证部分构造对象的子对象被正确销毁:

2 An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object has completed execution and a delegating constructor for that object exits with an exception, the object’s destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object.

整个过程称为“堆栈展开”:

3 The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called “stack unwinding.” If a destructor called during stack unwinding exits with an exception, std::terminate is called (15.5.1).

堆栈展开是广泛使用的技术的基础,称为 Resource Acquisition Is Initialization (RAII)。 .

请注意,如果未捕获到异常,则不一定要进行堆栈展开。在这种情况下,是否完成堆栈展开取决于实现。但是无论堆栈展开是否完成,在这种情况下,您都可以保证最终调用 std::terminate

C++11 15.5.1 The std::terminate() function [except.terminate]

2 … In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std::terminate() is called.

关于c++ - 在 C++ 中抛出后会调用析构函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8311457/

相关文章:

php - 禁止为 E_USER_WARNING 抛出异常

java - 如何为负数的可抛出异常编写完美的代码?使用assertThatThrownBy

c++ - 我如何在 C++ 中使用 template<typename>

c++ - 如何在 C++ 中使用泛型 vector

c++ - 如何将 SWIG 与 "using"一起使用

scala - 如何改进 "nested Try.. match "的代码?

Java:未捕获故意的 BadPaddingException

c++ - 了解 C++11 以来 std::forward 的实现

java - 如果将非法参数传递给 API 方法,何时抛出异常?

exception-handling - 给普通用户的错误消息中有多少信息?