构造函数作为函数try块 - 异常中止程序

时间:2015-01-13 11:35:49

标签: c++ c++11

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

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

#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警报&#34; abort()已被调用&#34;。所以我猜系统将此视为未捕获的异常并调用terminate()。

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

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

4 个答案:

答案 0 :(得分:30)

有一个相关的新手

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

基本上即使你没有投入你的catch区块,也会自动重新抛出异常

  

如果处理程序主体包含语句&#34; throw;&#34;接下来   block显然会重新抛出A :: A()或B :: B()的异常   发射。什么不那么明显,但在标准中明确说明,是   如果catch块没有抛出(要么重新抛出原始块   异常,或抛出新的东西),并控制到达结束   catch块的构造函数或析构函数,然后是原始的   异常会自动重新抛出。

答案 1 :(得分:22)

根据the cppreference.com documentation for function-try blocks,这是正常行为:构造函数或析构函数上的所谓 function-try-block 必须从其catch子句抛出,否则会有隐式重新抛出在catch-clause之后。

这很有道理:对象A未正确构造,因此不适合使用:它必须抛出异常。您必须确保构造对象的构造是否成功,即main()中的示例。

答案 2 :(得分:9)

无法在构造函数function-try-block中捕获异常。

n3376 15.2 / 15

  

如果控件到达结尾,则重新抛出当前处理的异常   构造函数或析构函数的function-try-block的处理程序。

你应该在对象创建的地方捕捉它。

答案 3 :(得分:0)

我建议你阅读文章:&#34; GotW#66构造函数失败&#34;在网站上:http://gotw.ca/gotw/066.htm