静态变量构造函数/析构函数的异常

时间:2013-06-09 04:50:07

标签: c++ try-catch

您好我在网络教程中找到了这一行。

  

当你声明一个静态对象并且析构函数抛出异常时会发生什么?   与静态构造函数异常一样,应用程序将崩溃。

如果对象是静态的,我无法理解有什么不同......

由于

1 个答案:

答案 0 :(得分:2)

我不确定你是否在询问有关抛出异常的构造函数或析构函数 - 问题语句是指析构函数,但示例代码和一些注释引用构造函数。

关于抛出的构造函数,它取决于静态对象是本地还是全局。本地静态对象是在控件第一次通过定义它们的作用域时构造的,异常处理程序应该为它们正常运行。在程序进入main()之前构造全局静态对象;因为你不能在全局范围内拥有try-catch块,如果全局静态对象的构造函数抛出,它基本上意味着你的应用程序在它离开起始门之前崩溃。

对于析构函数,一般来说,可以抛出异常的析构函数会产生严重的问题。 Herb Sutter在他的伟大着作“Exceptional C ++”中详细说明了原因,这本书可以在Google Books上找到here。基本上,如果析构函数可以抛出异常,则几乎不可能编写异常安全的代码。请考虑以下示例。

class T
{
    T() {}
    ~T() { throw 5; }
};

void foo()
{
    T t;
    throw 10;
}

foo()到达throw 10;语句时,控件将退出foo()的上下文,从而销毁进程中的本地对象t。这会调用t的析构函数,它会尝试抛出另一个异常。在C ++中,不可能同时抛出两个异常;如果抛出这样的第二个异常,程序会调用内置函数terminate(),它会听到它的声音并终止程序(您可以使用set_terminate设置自己的函数来调用,但这主要是为了进行自定义清理 - 您无法在功能完成后更改程序结束的事实。

避免这种情况的方法是确保析构函数永远不会抛出异常。静态对象可能无关紧要,因为正如celtschk所说,在程序终止之前不会调用析构函数,但作为一般规则,如果你发现自己编写了一个带有可以抛出异常的析构函数的类,你应该仔细考虑它是否真的是最好的方法。