2014-02-18 67 views
0

我想构造没有默认构造函数的类成员。 基本上我想做的事情在类的构造函数如下:有条件地构造不带默认构造函数的成员对象

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

,但我不知道是否有一种方法来构造成员,如果条款,但没有以防止在类的静态成员的副作用调用构造两次使用。

更新:我忘了提,我真的需要两个参数,但原则反正工作:

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

'级X :: X(配置):memberA(配置。 getBool?“yes”:“no”){}'? – Casey

+3

@Casey这应该是一个答案。 – juanchopanza

+0

是的,这基本上是伎俩,谢谢:) – Marste

回答

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)) 
{} 
0

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

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

相反,它是C++社区的主要缺陷之一,许多程序员不知道如何去做。不要使用'init'函数。 –

+0

@LightnessRacesinOrbit我同意:如果你不能处理'init()'函数,你不应该使用它。但是,当出现需要'init()'函数的情况时,你必须承认失败。并且存在这些情况。更好地确保,你*可以*处理它们。 – cmaster

+0

@cmaster:我从来没有见过这样的情况,这又是'init'函数放错位置的情况。正如贾罗德和凯西所表明的那样,实际上有多种更好的选择。 – MSalters

1

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

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