我不确定这是编译器的问题还是我做错了。我正在使用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()中包装对象的构造,那么异常被正确捕获并且程序正常终止。
有人可以告诉我,如果我在这里做错了吗?
答案 0 :(得分:30)
有一个相关的新手
基本上即使你没有投入你的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