如何在抛出异常时处理失败的构造函数是不允许的

时间:2010-07-27 22:30:08

标签: c++ constructor exception

我正在查看Google C ++样式指南,他们已经决定not to use exceptions in C++ code,而是依赖于返回值。

我的问题是:在这种情况下,你如何处理构造函数中的失败,因为你不能在那些函数中返回值。

谢谢!

6 个答案:

答案 0 :(得分:7)

我的第一直觉是将失败点从构造函数中取出,并创建一个初始化方法。

这样你可以创建你的对象而不用担心失败,然后调用init()函数。该函数可以返回类似int的成功/失败,例如,如果发生故障,则返回-1。

是的,这是一个额外的步骤,但它确实让你无法使构造函数失败

答案 1 :(得分:4)

这很丑陋,但这样做的方法是保留对象的“特殊状态”,意思是“构造失败”。然后你必须查询该状态。啊!

答案 2 :(得分:2)

他们在构造函数中基本上什么都不做。

同样来自Google C ++风格指南: 在构造函数中工作 链接▶ 通常,构造函数应该只将成员变量设置为其初始值。任何复杂的初始化都应该采用显式的Init()方法。

答案 3 :(得分:2)

您可以执行以下操作:

class X;
class Y;

class Foo
{
   public:
      //! This function validates the input, and returns an error status if
      //! the Foo can not be created. Otherwise we return a successful status
      //! and output points to a newly constructed Foo. The Foo constructor 
      //! is only called once the inputs are validated.
      //! No exceptions are thrown.
      static Status buildInstance(X const& x, Y const& y, std::auto_ptr<Foo>& output);

   private:
      Foo(X const& x, Y const& y);
};

我过去经常使用这种模式(因为我不得不),但是说,我更喜欢我的构造函数抛出异常。上述情况充其量是不优雅的,最糟糕的是相当繁琐。

答案 4 :(得分:2)

我是C ++的新手,所以我的意见不值得这么多;但我至少遇到过几种不同的方法。

在我最近使用的一个库中,每个构造函数都有一个int&参数,它返回构造的状态;此库的文档声明如果构造结果无效,它将调用未定义的行为。这种方法使调用者有责任确保不使用无效类。

TheClass::TheClass(int &result)
{
    result = -1; // or some error value
    // do lots of initialisation
    result = 0; // success
}

我看到的另一个有is_valid()方法。如果构造失败,则将布尔成员变量设置为false并从此is_valid()方法返回(此方法还检查了其他一些内容)。我设法看到了这个源,并发现每个成员函数都以if(is_valid())语句开头。我不能说我是这种方法的粉丝。

TheClass::TheClass() : m_valid(false)
{
    // do the initialisation
    if (everything_ok)
        m_valid = true;
}

void TheClass::method()
{
    if (!is_valid()) return;
    // do some work
}

我最近读到过,异常并不像过去那样缓慢和笨拙,而且可以优雅地实现它们。谷歌可能出于任何原因禁止它们,但它们仍然是C ++语言的一部分。你可以使用你提供的工具,而不是用螺丝刀建造房屋。

答案 5 :(得分:1)

您可以设置一个类/对象字段来检查是否发生错误。