有条件地构造没有默认构造函数的成员对象

时间:2014-02-18 10:24:29

标签: c++ constructor

我想有条件地构造没有默认构造函数的类成员。 基本上我想在类构造函数中执行以下操作:

class X{
public:
    X(Config config) {
        if (config.getBool) memberA("yes");
        else memberA("no");
    }
}

问题在于,如前所述,memberA类没有默认构造函数,因此编译器无法构造它导致错误。 显然我可以这样做:

class X{
public:
    X(Config config) : memberA("yes") {
    if (!config.getBool) memberA = MemberAClass("no");
    }
}

但是我想知道是否有办法使用if子句构造成员但是没有调用构造函数两次以防止类的静态成员产生副作用。

更新:我忘了提到我实际上需要两个参数,但原则仍然有效:

X::X(Config cfg):member(cfg.getBool()?"yes":"no",cfg.getBool()?1:2){};

3 个答案:

答案 0 :(得分:4)

您必须使用构造函数初始化列表和条件运算符(而不是if),如下所示:

X::X(const Config& config) : memberA(config.getBool() ? "yes" : "no")
{}

或创建一个函数来计算正确的参数:

const char* compute_memberA_arg(const Config& config) {
    if (config.getBool()) { return "yes"; }
    else { return "no"; }
}

X::X(const Config& config) : memberA(compute_memberA_arg(config))
{}

答案 1 :(得分:1)

鉴于更新,我建议使用(静态)辅助方法:

MemberType X::initMemberA(bool flag) {
  return flag ? MemberType("yes", 1) : MemberType("no", 2);
}
X::X(Config cfg) : memberA(initMemberA(cfg.getBool())) { }

答案 2 :(得分:0)

这是C ++的主要缺陷之一,您无法将构造的构造嵌入到构造函数代码中。当你需要根据参数使用不同的构造函数时,这尤其令人讨厌。在这些情况下,最佳解决方法是将成员初始化(部分)移动到init()函数中。然后你可以做这样的事情:

class Foo {
    Bar bar;
public:
    Foo(bool flag) {
        if(flag) {
            bar.init("init from string");
        } else {
            bar.init(3, 7, 5);
        }
    }
};