您好我在网络教程中找到了这一行。
当你声明一个静态对象并且析构函数抛出异常时会发生什么? 与静态构造函数异常一样,应用程序将崩溃。
如果对象是静态的,我无法理解有什么不同......
由于
答案 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所说,在程序终止之前不会调用析构函数,但作为一般规则,如果你发现自己编写了一个带有可以抛出异常的析构函数的类,你应该仔细考虑它是否真的是最好的方法。