首页 > 解决方案 > 为什么我的析构函数异常没有被捕获

问题描述

class D
{
public:
    ~D() { throw std::exception(); }
};
int main()
{
    try
    {
        try
        {
            D d;
        }
        catch (...)
        {
            cout << "1";
        }
    }
    catch (std::exception& e)
    {
        cout << "2";
    }
}

我的理解是这应该在 2 中被捕获。但它没有被捕获,而是程序被终止。

标签: c++exception

解决方案


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

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

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

请注意,即使它在技术上是合法的,但通常认为在析构函数中抛出未捕获的异常是一个坏主意,因为它会使您的类在可能抛出可处理异常的任何上下文中基本上无法使用。您可以在c++ exception in destructor中阅读更多信息(这不是严格的重复,但完全涵盖了您的场景)。


推荐阅读