![](/img/trans.png)
[英]An exception gets thrown twice from a constructor with a function-try-block
[英]Constructor as a function try block - Exception aborts program
我不确定这是编译器的问题还是我做错了什么。 我正在使用 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 警报“abort() 已被调用”。 所以我猜系统将此视为未捕获的异常并调用 terminate() 。
另一方面,如果我将 main() 中对象的构造包装在 try-catch 块中,则异常被正确捕获并且程序正常终止。
有人可以告诉我我在这里做错了吗?
有一个相关的 gotw
基本上即使你不抛出你的catch块,异常也会自动重新抛出
如果处理程序主体包含语句“throw;” 那么 catch 块显然会重新抛出 A::A() 或 B::B() 发出的任何异常。 不太明显但在标准中明确说明的是,如果 catch 块没有抛出(重新抛出原始异常,或抛出新的异常),并且控制到达构造函数或析构函数的 catch 块的末尾,则原始异常会自动重新抛出。
根据cppreference.com 函数try
块的文档,这是正常行为:构造函数或析构函数上的所谓函数 try 块必须从其 catch 子句中抛出,否则在 catch 子句之后存在隐式重新抛出.
这是完全有道理的:对象A
没有被正确构造,因此不处于适合使用的状态:它必须抛出异常。 您必须确保在构造对象的地方构造是否成功,即在main()
中的示例的情况下。
无法在构造function-try-block
捕获异常。
n3376 15.2/15
如果控制到达构造函数或析构函数的函数尝试块的处理程序的末尾,则重新抛出当前处理的异常。
您应该在对象创建位置捕获它。
我建议您阅读网站上的文章:“GotW #66 Constructor Failures”: http ://gotw.ca/gotw/066.htm
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.