代码之家  ›  专栏  ›  技术社区  ›  recipriversexclusion

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

  •  2
  • recipriversexclusion  · 技术社区  · 15 年前

    我正在看谷歌C++风格指南,他们已经决定了。 not to use exceptions in C++ code ,而依赖于返回值。

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

    谢谢!

    6 回复  |  直到 15 年前
        1
  •  7
  •   Dunderklumpen    15 年前

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

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

    是的,这是一个额外的步骤,但它确实让您绕过了不能使构造函数失败的问题。

        2
  •  4
  •   John    15 年前

    这很难看,但要做到这一点,方法是保留对象的“特殊状态”,以表示“构建失败”。然后您必须查询那个状态。呸!

        3
  •  2
  •   rhinoinrepose    15 年前

    它们基本上不在构造函数中执行任何操作。

    也从谷歌C++风格指南: 构造函数中完成工作 链接链接 一般来说,构造函数应该只将成员变量设置为其初始值。任何复杂的初始化都应该在显式init()方法中进行。

        4
  •  2
  •   Craig Wright    15 年前

    您可以执行以下操作:

    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);
    };
    

    在过去,我经常使用这种模式(因为我必须这样做),但也就是说,我更喜欢我的构造函数抛出异常。上面的内容充其量是不雅的,充其量是相当繁琐的。

        5
  •  2
  •   dreamlax    15 年前

    我对C++是新的,所以我的观点不值得这么多,但是我至少遇到了几种不同的方法。

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

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

    我看到的另一个有 is_valid() 方法。如果构造失败,则将布尔成员变量设置为false,并从此变量返回 ISSUM验证() 方法(这个方法也检查了其他一些东西)。我设法找到了这个的源代码,发现每个成员函数都是从 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++语言的一部分。与其用螺丝刀盖房子,不如用别人给你的工具。

        6
  •  1
  •   Federico klez Culloca    15 年前

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