7

嗨,我在网络上的教程中找到了这一行。

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

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

谢谢

4

1 回答 1

3

我不确定您是否在询问引发异常的构造函数或析构函数 - 问题陈述指的是析构函数,但示例代码和一些注释指的是构造函数。

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

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

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

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

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

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

于 2013-06-09T19:53:03.867 回答