无法初始化初始值设定项列表之外的字段

Can't initialize field outside initializer list

本文关键字:列表 字段 初始化      更新时间:2023-10-16

我遇到了一些看起来很容易的事情,所以我一定忽略了一些东西。

我需要构造一个类,该类的字段也是一个类(非 POD(。字段的类具有默认构造函数和"真实"构造函数。问题是我真的无法在初始值设定项列表中构造字段,因为实际上构造函数有一个参数,该参数是一个向量,需要一个有点复杂的 for 循环来填充。

下面是重现该问题的最小示例。

ConstructorsTest.h:

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

构造函数测试.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)移动到初始值设定项列表会导致编译成功。

其他类似的线程提到对象必须具有默认构造函数,或者它不能是 const。在这里,这两个要求似乎都得到了满足。

不能在构造函数的主体中初始化数据成员。(the_property(4);只是试图将the_property调用为函子。您只能像以下方式分配它们:

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

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

您可以添加一个成员函数来生成必要的数据,并使用它来初始化成员初始值设定项列表中的数据成员。

class ConstructorsTest {
...
static int generateData();
};
int ConstructorsTest::generateData() {
return ...;
}
ConstructorsTest::ConstructorsTest() : the_property(generateData()) {
}

不能将变量初始化两次1构造函数启动后,所有成员子对象都将被构造。如果未在构造函数中提供成员初始值设定项,或在类定义中提供默认成员初始值设定项,则它将执行默认初始化。无论它采取什么形式,你都无法再次构建它。

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

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

1: 嗯...你可以,但不是那样的。你真的不应该遇到这么简单的情况。