从构造函数的初始化列表中捕获异常

时间:2008-10-01 22:57:13

标签: c++ exception

这是一个好奇的人。我有一个A类。它有一个B类项目,我想在A的构造函数中使用初始化列表初始化,如下所示:

class A {
    public:
    A(const B& b): mB(b) { };

    private:
    B mB;
};

有没有办法捕获mB复制构造函数可能在使用初始化列表方法时抛出的异常?或者我是否必须在构造函数的大括号中初始化mB才能获得try / catch?

5 个答案:

答案 0 :(得分:81)

阅读http://weseetips.wordpress.com/tag/exception-from-constructor-initializer-list/

编辑:经过多次挖掘后,这些被称为“功能尝试块”。

我承认在我去看之前我也不知道这一点。你每天都学到东西!我不知道这是否是对我现在使用C ++有多少,我缺乏C ++知识或者经常使用拜占庭式功能的起诉书。好吧 - 我还是喜欢它:)

为了确保人们不必跳转到另一个站点,构造函数的函数try块的语法结果是:

C::C()
try : init1(), ..., initn()
{
  // Constructor
}
catch(...)
{
  // Handle exception
}

答案 1 :(得分:17)

这不是特别漂亮:

A::A(const B& b) try : mB(b) 
{ 
    // constructor stuff
}
catch (/* exception type */) 
{
    // handle the exception
}

答案 2 :(得分:4)

我知道自从讨论开始以来已经有一段时间了。但是,Adam提到的try-and-catch结构是C ++标准的一部分,并得到Microsoft VC ++和GNU C ++的支持。 这是有效的程序。顺便说一句,catch会自动生成另一个异常,以表示构造函数失败。

#include <iostream>
#include <exception>
#include <string>

using namespace std;

class my_exception: public exception
{
  string message;
public:
  my_exception(const char* message1)
  {
    message = message1;
  }

  virtual const char* what() const throw()
  {
     cout << message << endl;
     return message.c_str();
  }

  virtual ~my_exception() throw() {};
};

class E
{
public:
    E(const char* message) { throw my_exception(message);}
};

class A
{
    E p;
public:
    A()
  try :p("E failure")
    {
            cout << "A constructor" << endl;
    }
  catch (const exception& ex)
    {
        cout << "Inside A. Constructor failure: " << ex.what() << endl;
    }
};


int main()
{
    try
    {
        A z;
    }
    catch (const exception& ex)
    {
        cout << "In main. Constructor failure: " << ex.what() << endl;
    }
    return 0;
}

答案 3 :(得分:1)

您可以使用延迟初始化,即在MyClass中为Reader设置unique_ptr并使用new创建它。这样,你甚至不需要标志has_reader,但你可以看看你的unique_ptr是否是初始的。

system()

当然,也有一些解决方案没有使用例外,但我认为这是你设置的先决条件。

答案 4 :(得分:0)

我不知道你是如何用初始化列表语法做的那样,但我也有点怀疑你能通过在构造函数中捕获异常来做任何有用的事情。显然,它取决于类的设计,但在什么情况下你将无法创建“mB”,并且仍然有一个有用的“A”对象?

你也可以让异常渗透,并在调用A的构造函数的任何地方处理它。