无法初始化初始化列表外的字段

时间:2017-07-14 01:57:43

标签: c++ c++11 constructor initialization initializer-list

我遇到一些看似非常简单的问题,所以我必须忽视一些事情。

我需要构建一个具有同样是一个类(非POD)的字段的类。该字段的类具有默认构造函数和“真实”构造函数。问题是我真的无法在初始化列表中构造字段,因为实际上构造函数有一个参数,它是一个需要稍微复杂的for循环来填充的向量。

这是一个重现问题的最小例子。

ConstructorsTest.h:

class SomeProperty {
public:
    SomeProperty(int param1); //Ordinary constructor.
    SomeProperty();           //Default constructor.
    int param1;
};

class ConstructorsTest {
    ConstructorsTest();
    SomeProperty the_property;
};

ConstructorsTest.cpp:

#include "ConstructorsTest.h"

ConstructorsTest::ConstructorsTest() {
    the_property(4);
}

SomeProperty::SomeProperty(int param1) : param1(param1) {}
SomeProperty::SomeProperty() : param1(0) {} //Default constructor, doesn't matter.

但这会产生编译错误:

ConstructorsTest.cpp: In constructor 'ConstructorsTest::ConstructorsTest()':
ConstructorsTest.cpp:4:19: error: no match for call to '(SomeProperty) (int)'
    the_property(4);
                  ^

它没有给出任何建议,就像它通常可以用来代替什么功能一样。

在上面的例子中,我只是初始化初始化列表中的the_property,但实际上4实际上是一个需要先生成的复杂向量,所以我真的不能。将the_property(4)移动到初始化列表会导致编译成功。

其他类似的主题提到该对象必须有default constructorit can't be const。这两个要求似乎都得到了满足。

2 个答案:

答案 0 :(得分:2)

您无法在构造函数体内初始化数据成员。 (the_property(4);只是尝试将the_property作为仿函数调用。)您只能将它们分配为:

ConstructorsTest::ConstructorsTest() {
    the_property = ...;
}
  

但实际上4实际上是一个需要先生成的复杂载体

您可以添加生成必要数据的成员函数,并使用它来初始化member initializer list中的数据成员。 e.g。

class ConstructorsTest {
    ...
    static int generateData();
};

int ConstructorsTest::generateData() {
    return ...;
}

ConstructorsTest::ConstructorsTest() : the_property(generateData()) {
}

答案 1 :(得分:0)

您无法初始化变量两次 1 当构造函数启动时,所有成员子对象将被构造。如果未在构造函数中提供成员初始值设定项,或者在类定义中未提供默认成员初始值设定项,则它将执行默认初始化。无论采用何种形式,您都无法再次构建它。

复杂的多语句初始化最好通过lambda函数完成:

ConstructorsTest::ConstructorsTest()
  : the_property( []{ /* Do Complex Initialization */}() )
{
}

1 :嗯......你可以,但不是那样的。对于像这样简单的案件,你真的不应该这样做。