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”); } } |
问题在于,如前所述,memberA 类没有默认构造函数,因此编译器无法构造它,从而导致错误。
显然我可以这样做:
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){};
|
- class X::X(config) : memberA(config.getBool ?”yes” :”no”) {} ?
- @Casey这应该是一个答案。
- 是的,这基本上可以解决问题,谢谢:)
您必须使用构造函数初始化列表和条件运算符(而不是 if),如下所示:
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 的主要缺陷之一,您不能将成员的构造嵌入到构造函数代码中。当您需要根据参数使用不同的构造函数时,这尤其令人讨厌。在这些情况下,最好的解决方法是将成员的初始化(部分)移动到 init() 函数中。然后你可以做这样的事情:
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); } } }; |
- 相反,这是 C 社区的主要缺陷之一,许多程序员不知道如何去做。不要使用 init 函数。
- @LightnessRacesinOrbit 我同意:如果您无法处理 init() 函数,则不应使用它。但是,每当出现需要 init() 函数的情况时,您都必须认输。而这些情况是存在的。最好确保,您可以处理它们。
- @cmaster:我从未见过这种情况,这又是 init 函数放错位置的情况。正如 Jarod 和 Casey 所表明的,实际上有多种更好的选择。
- @MSalters确实,这里的示例都没有严格要求使用 init() 函数,甚至我给出的示例也没有,即使在这种情况下使用 init() 函数可能是最好的主意。但我见过一个需要 init() 函数的案例。在评论中解释有点过于复杂,但它与动态创建未知类的实例有关,这些实例需要根据一些描述相互了解。类似于在 MacOS X 上加载 .nib 文件,但有一些不同的怪癖。
来源:https://www.codenong.com/21850785/