作为函数的构造函数尝试块 – exception中止程序

我不确定这是编译器的问题,还是我做错了什么。 我正在使用Visual Studio 2013编译器。

我有一个类,我需要获取大量的资源在我的构造函数初始化列表中,其中大部分可以抛出exception。 我将函数try块中的成员初始值设定项列表封装起来,并在那里发现exception。 但是,即使catch子句不重新抛出exception,我的程序仍然中止。 我不允许发布实际的代码。 所以我用这个等效的演示代码重现了这个问题。 有人可以帮我解决这个问题吗?

#include <iostream> using namespace std; class A{ public: A() try : i{ 0 }{ throw 5; } catch (...){ cout << "Exception" << endl; } private: int i; }; int main(){ A obj; } 

在执行这个代码时,我得到了一个windows警报“abort()已被调用”。 所以我猜系统将这个作为一个未捕获的exception,并调用terminate()。

另一方面,如果我将main()中的对象的构造包装在try-catch块中,则exception被正确捕获,程序正常终止。

有人可以告诉我,如果我在这里做错了吗?

有一个相关的gotw

http://gotw.ca/gotw/066.htm

基本上,即使你不扔你的catch块,exception会自动重新抛出

如果处理程序主体包含语句“throw” 那么catch块显然会重新抛出A :: A()或B :: B()发出的exception。 不太明显,但在标准中清楚地表明,如果catch块不抛出(重新抛出原始exception,或抛出新东西),并且控制到达构造函数或析构函数的catch块的末尾,那么原始exception会自动重新生成。

根据cppreference.com关于函数块的文档,这是正常的行为:构造函数或析构函数上的所谓的函数尝试块必须抛出它的catch子句,否则在catch子句之后有一个隐含的重新抛出。

这是非常有意义的:对象A没有被正确构造,因此不处于适合使用的状态:它必须抛出exception。 你必须确保在构造对象的地方构造是否成功,也就是说你的例子在main()

在构造function-try-block不能捕获exception。

n3376 15.2 / 15

如果控件到达构造函数或析构函数的function-try-block处理程序的末尾,则会重新处理当前处理的exception。

你应该把它在对象创build的地方。

我build议你阅读网站上的文章:“GotW#66构造失败”: http ://gotw.ca/gotw/066.htm