【问题标题】:c++ how to handle initializer that throws exceptionsc ++如何处理引发异常的初始化程序
【发布时间】:2015-04-07 01:40:18
【问题描述】:

非常简单的问题,如何处理初始化可能从其构造函数中抛出异常的类成员变量?

class main
{
public:
    main() c(...) {};
private:
    my_class c;
};

class my_class
{
public:
    inline my_class() : o(...) { };

private:
    some_obj o;
};

显然您不能在构造函数初始化程序中尝试捕获异常,那么在构造函数中的 try catch 块中构造对象是否更合适?

这是一个顶级类,因此处理异常以让用户知道发生了什么并优雅地退出比让程序因异常而崩溃更重要?

class main
{
public:
    main()
    {
        try
        {
            c(...);
        }
        catch(...)
        {
            ...
        }
    };
private:
    my_class c;
};

但是,这是行不通的,因为对象在构造函数中初始化之前会被初始化一次,因此如果对象抛出异常,程序可能会崩溃。

【问题讨论】:

  • 您可以在构造函数中使用函数try-block,以捕获成员初始化期间引发的异常。请注意,这里唯一明智的做法是重新抛出异常。在大多数情况下,让程序继续处理部分构造的对象是糟糕的设计。
  • @MattMcNabb:构造函数或析构函数上的 function-try-block 在异常处理程序结束时自动重新抛出。
  • @MattMcNabb 是的,我不打算继续该程序,而是尝试执行更优雅的退出。

标签: c++ exception constructor


【解决方案1】:

您需要的是function-try-block。它专为解决您的问题而设计。

class main
{
public:
    main() try : c(...)
    {
        std::cout << "constructed, c = " << c << std::endl;
    }
    catch(...)
    {
        std::cerr << "failed to construct c = " << c << std::endl;
    } // implicit throw; here

private:
    my_class c;
};

【讨论】:

  • 有趣,没见过这个。这是 c++11+ 的功能吗?你可以在构造函数中使用这些吗?
  • 没有。这是 C++ 一直以来的一个特性。是的,它可以与构造函数一起使用。
  • @FranciscoAguilera 这存在特别是因为构造函数的初始化列表允许在函数体之外抛出可抛出代码。这就是它的用途。
【解决方案2】:

为什么不能在构造函数中捕获错误?根据this question,这似乎是标准做法。

【讨论】:

  • 因为对象在你在构造函数中初始化之前就被初始化了。
  • @FranciscoAguilera,该链接包含函数 try 块语法。
猜你喜欢
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 2010-11-16
  • 2016-03-27
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 2013-05-15
相关资源
最近更新 更多