析构函数抛出异常

时间:2015-06-29 04:07:07

标签: c++ destructor

我试图理解为什么析构函数抛出异常是一个非常糟糕的主意。通过谷歌搜索,我理解如果析构函数抛出,比如说,在块范围对象的销毁过程中,对象的销毁就会停止,如果还有其他对象,那么我们就会发生内存泄漏。

但是就其本身而言,抛出异常的析构函数是如此糟糕?例如(完整示例):

struct A
{
    int a;
    char b;
    A() : a(10), b('a') { }
    ~A(){ throw std::exception(); }
};

int main()
{
    A a; //destructor throws, but there're no more objects to destruction 
         //therefore I think there's no memory leak
}

我们在上面的程序中获得了UB吗?

1 个答案:

答案 0 :(得分:5)

在这个简单的例子中,抛出了bar()中的异常并且展开了堆栈,破坏了a,这会引发另一个异常。在这种情况下可以抛出哪个异常?

struct A
{
    int a;
    char b;
    A() : a(10), b('a') { }
    ~A(){ throw std::exception(); }
};
void bar () 
{
    A a;
    throw std::exception();
}
int main()
{
    bar();
}

来自C++ FAQ

  

在堆栈展开期间,所有堆栈中的所有本地对象   帧被破坏。如果其中一个析构函数抛出异常   (假设它抛出了一个Bar对象),C ++运行时系统处于一种不可取的状态   情况:它应该忽略Bar并最终进入} catch(Foo e)   {它最初在哪里?它应该忽略Foo并且看起来   for a catch(Bar e){handler?也没有好的答案   选择失去了信息。

     

所以C ++语言保证它会调用terminate()   point和terminate()终止进程。