我必须初始化构造函数中的所有内容吗?

时间:2016-09-06 02:01:37

标签: c++ constructor initialization

我相信任何未初始化的内容都会自动初始化,这有点危险(而且做法很差)。我也理解初始化列表通常更有效(并且在某些情况下是必要的),但是,我想在将它们分配给成员变量之前通过函数调用验证一些参数。

例如,使用典型的赋值构造函数,我有类似的东西:

class MyObj
{
    private:
        int one_;
        int two_;
        DiffObj diffObj_;

    ... // other stuff
}

MyObj::MyObj(int a, int b, std::string type, std::vector<double> params)
{
    one_ = a;
    two_ = b;
    if (verifyType(type, params))
    {
        diffObj_ = createDiffObj(params);
    }
}

虽然有这种情况,我怎么能利用初始化列表?我想或许可以通过初始化构造函数中的一些参数并使用单独的调用来初始化其余参数,但我不确定这是否是犹太教。

MyObj::MyObj(int a, int b) :
    one_(a),
    two_(b)
    {}

MyObj::initializeDiffObj(std::string type, std::vector<double> params)
{
    if (verifyType(type, params))
    {
        diffObj_ = createDiffObj(params);
    }
}

2 个答案:

答案 0 :(得分:2)

这样的事情是完全合理的。你可以有一个初始化列表并在你的构造函数中做一些工作,你不必选择一个。

 class MyClass {
     public:
         MyClass(int a, SomeStruct b)
          : _a(a) {
              if (isValid(b)) {
                   // Initialize _b
                   _b = createWeirdThingFromSomeStruct(b);
              }
         }
     private:
         int _a;
         WeirdThing _b;
};

答案 1 :(得分:1)

如果构造函数未为成员提供初始值设定项,则该成员 default-initialized 。对于int,这意味着根本没有初始化;对于具有用户提供的构造函数的类类型,它意味着调用该构造函数。

理想情况下,构造函数初始化列表应该完成所有成员的初始化。这是为您的情况做到这一点的一种方法:

MyObj::MyObj(int a, int b, std::string type, std::vector<double> params)
    : one_(a), two_(b), 
      diffobj( verifyType(type, params), std::move(params) )
{
}

这个(ab)使用逗号运算符在verifyType初始化期间适应对diffobj的调用。如果验证失败,verifyType函数应抛出异常。