Constructing member objects without default constructor conditionally
我想有条件地构造没有默认构造函数的类成员。
基本上我想在类构造函数中执行以下操作:
1 2 3 4 5 6 7 | class X{ public: X(Config config) { if (config.getBool) memberA("yes"); else memberA("no"); } } |
问题在于,如前所述,
显然我可以这样做:
1 2 3 4 5 6 | class X{ public: X(Config config) : memberA("yes") { if (!config.getBool) memberA = MemberAClass("no"); } } |
但我想知道是否有一种方法可以使用 if 子句构造成员,但不调用构造函数两次,以防止类的静态成员产生副作用。
更新:我忘了提到我实际上需要两个参数,但原理仍然有效:
1 | X::X(Config cfg):member(cfg.getBool()?"yes":"no",cfg.getBool()?1:2){}; |
您必须使用构造函数初始化列表和条件运算符(而不是
1 2 | X::X(const Config& config) : memberA(config.getBool() ?"yes" :"no") {} |
或创建一个函数来计算正确的参数:
1 2 3 4 5 6 7 | 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 2 3 4 | MemberType X::initMemberA(bool flag) { return flag ? MemberType("yes", 1) : MemberType("no", 2); } X::X(Config cfg) : memberA(initMemberA(cfg.getBool())) { } |
这是 C 的主要缺陷之一,您不能将成员的构造嵌入到构造函数代码中。当您需要根据参数使用不同的构造函数时,这尤其令人讨厌。在这些情况下,最好的解决方法是将成员的初始化(部分)移动到
1 2 3 4 5 6 7 8 9 10 11 | class Foo { Bar bar; public: Foo(bool flag) { if(flag) { bar.init("init from string"); } else { bar.init(3, 7, 5); } } }; |