繁体   English   中英

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

[英]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

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

基本上即使你不抛出你的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM