我运行了一个样例程序,确实会调用栈分配对象的析构函数,但这是否由标准保证呢?
3 在从 try 块到 throw 表达式的路径上构造的自动对象的调用析构函数的过程称为 “堆栈展开” 。如果在堆栈展开期间调用的析构函数退出并引发异常,则会调用 std::terminate (15.5.1)。
堆栈展开是广泛使用的 资源获取即初始化 (RAII) 技术的基础。
请注意,如果未捕获异常,则不一定执行堆栈展开。在这种情况下,是否执行堆栈展开取决于实现。但无论是否执行堆栈展开,在这种情况下,你都保证会最终调用 std::terminate
。
C++11 15.5.1 函数 std::terminate() [except.terminate]
2 … 在找不到匹配处理程序的情况下,实现定义在调用
std::terminate()
之前是否展开堆栈。
是的,在堆栈展开时,包括由于抛出异常而导致的展开,析构函数得到保证会被调用。有几个关于异常需要注意的技巧:
terminate()
您的进程。我很想看到反例... - DevSolartry
)。Visual C++ 从未实现标准的检查函数,而且该函数也不太适当。因此,这有点棘手,但并非完全无法解决,因为使用代码可以设计解决方案。 - Cheers and hth. - Alf如果一个抛出异常被捕获,那么通常cpp操作会继续执行。这包括析构函数和堆栈弹出。但是如果异常未被捕获,则不能保证堆栈弹出。
此外,我的移动编译器无法捕获裸抛或空抛。
示例:
#include <Jav/report.h>
int main()
{
try { throw; }
catch(...) { rep("I bet this is not caught"); }
}