不允许抛出异常时如何处理失败的构造函数 我正在看谷歌C++风格指南,他们已经决定了,依赖于返回值。p>

不允许抛出异常时如何处理失败的构造函数 我正在看谷歌C++风格指南,他们已经决定了,依赖于返回值。p>,c++,constructor,exception,C++,Constructor,Exception,我的问题是:在这种情况下,如何处理构造函数中的失败,因为在这些构造函数中不能返回值 谢谢 您可以设置一个类/对象字段来检查是否发生了错误。我的第一反应是从构造函数中取出失败点,并创建一个初始化方法 通过这种方式,您可以创建对象而不用担心失败,然后调用init()函数。该函数可以返回类似int的成功/失败信息,例如,如果失败发生,则返回-1 是的,这是一个额外的步骤,但它确实可以让你避免构造函数失败。这很难看,但方法是保留对象的“特殊状态”,表示“构造失败”。然后,您必须查询该状态。啊 他们的构造

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


谢谢

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

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

通过这种方式,您可以创建对象而不用担心失败,然后调用init()函数。该函数可以返回类似int的成功/失败信息,例如,如果失败发生,则返回-1


是的,这是一个额外的步骤,但它确实可以让你避免构造函数失败。这很难看,但方法是保留对象的“特殊状态”,表示“构造失败”。然后,您必须查询该状态。啊

他们的构造函数基本上什么都不做

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

您可以执行以下操作:

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);
};
X类;
Y类;
福班
{
公众:
//!此函数用于验证输入,并在以下情况下返回错误状态
//!无法创建Foo。否则,我们将返回成功状态
//!和输出指向新构造的Foo。Foo构造函数
//!仅在输入验证后调用。
//!不会引发任何异常。
静态状态buildInstance(X常量和X,Y常量和Y,std::auto_ptr&output);
私人:
Foo(X const&X,Y const&Y);
};

我过去经常使用这种模式(因为我不得不这样做),但也就是说,我更喜欢我的构造函数抛出异常。以上是最不雅的,最差的是非常繁琐的。

< P>我是C++新手,所以我的观点不值得这么多;但我至少遇到过两种不同的方法

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

TheClass::TheClass(int &result)
{
    result = -1; // or some error value
    // do lots of initialisation
    result = 0; // success
}
我看到的另一个方法是valid()方法。如果构造失败,一个布尔成员变量被设置为false,并从此
is\u valid()
方法返回(此方法还检查了一些其他事项)。我设法查看了它的源代码,发现每个成员函数都以一个
if(is\u 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++语言的一部分。你可以使用所给的工具,而不是仅仅用螺丝刀来建造房子。

如果对象没有建造,你如何检查它?@Joe,在构造器的开头设置标志,在结尾清除标志。反之亦然,不要用谷歌的代码指南来设计现代代码,这与优秀的C++实践相比是可怕的。他们的指南是针对他们现有的代码库,这是不好的C++。如果你点击谷歌页面上的点旁边的小播放按钮,你会发现他们正把这一点作为一个赞成使用异常的专业。另外,请阅读“决定”部分。他们指出了GMan的观点——这个决定是为了避免破坏(或重写)整个现有的代码库。。。所以,如果不是使用异常,那么你就不能正确使用C++。请参阅一个非常详细的解释为什么不执行一个In()例程。一般来说(我主要是java编码器),我不喜欢在构造函数中出现异常的可能性。我倾向于采用C++的方法。不要用C++编程java,C++中的C++程序,完全违背RAII。这就是Java程序员感到困惑的原因;他们没有RAI,似乎这种做法违背了良好的C++实践;但是,考虑到这个限制,我认为这是最简单的方法。您可以尝试分配内存,但失败。@recip:这将是一个复杂的初始化过程。