【发布时间】:2015-06-12 16:40:59
【问题描述】:
考虑一下:
class Foo {
private:
Bar x;
public:
Foo(int a) { // no initialization here since constructor is dependent on a following if-block
if (a==0) x=Bar(12,'a', 34); // some (int, char, int) constructor of Bar
else x=Bar(13); // (int) constructor of Bar
}
}
这应该做的是检查参数a的值,并根据a的值使用某个构造函数和某些参数初始化Bar x。然而问题是,这当然被编译器读取为
Foo(int a): Bar() { // !
if (a==0) x=Bar(12,'a', 34); // some Bar(int, char, int) constructor of Bar
else x=Bar(13); // Bar(int) constructor of Bar
}
编译器将 Bar() 添加到初始化列表中,因为我省略了它。它现在被双重初始化,一次使用它的 () 构造函数,一次在函数体中。但是如果初始化 Bar(即使使用它的默认构造函数)非常昂贵(关于性能)并且我不能或不想要这种双重初始化呢?
在实际的构造函数体中之前,我如何才能不初始化 Bar x? 如果不可能,我将如何最好地解决这个问题?
补充:为什么 C++ 是这样设计的?为什么它在实际的构造函数体之前强制初始化成员?
【问题讨论】:
-
我能想到的第一个解决方案(同时将
Bar直接存储在Foo中)是使x成为变体成员并使用placement new 构造它。但这需要手动编写所有其他特殊成员函数。 -
@RemyLebeau 并非如此,因为该用户正在询问与包含类相同的类的构造函数委托,而在我的情况下 Foo 和 Bar 是不同的类。不过,不确定在这种情况下这是否是一个非常重要的区别。
-
您可以将
a原样传递给Bar构造函数,并根据需要将其委托给其他Bar构造函数。
标签: c++ parameters constructor default-constructor initialization-list