为什么没有捕获我来自析构函数的异常

why my exception from a destructor is not caught

本文关键字:析构函数 异常 为什么      更新时间:2023-10-16
class D
{
public:
~D() { throw std::exception(); }
};
int main()
{
try
{
try
{
D d;
}
catch (...)
{
cout << "1";
}
}
catch (std::exception& e)
{
cout << "2";
}
}

我的轻描淡写是,这应该在 2 中捕获。但它没有被抓住,而是程序被终止。

在 C++11 中,析构函数是隐式noexcept的,因此如果析构函数抛出未在析构函数本身中捕获的异常,则会自动调用std::terminate

甚至在此之前,在堆栈展开期间抛出未捕获异常的析构函数也会导致std::terminate被调用,因此如果析构函数被堆栈冒泡的其他异常调用,您正在执行的操作将不起作用。

如果这不是问题,则可以显式声明析构函数为~D() noexcept(false)(如果析构函数不是由导致堆栈展开的其他异常触发的,这将允许异常从析构函数中冒出(。

请注意,尽管它在技术上是合法的,但在析构函数中抛出未捕获的异常通常被认为是一个坏主意,因为它会使您的类在任何可能引发可处理异常的上下文中基本上无法使用。您可以在析构函数中的 c++ 异常中阅读更多内容(这不是严格的重复项,但完全涵盖了您的方案(。