使用委托构造函数时的成员初始化

我已经开始尝试 C + + 11标准,我发现了 这个问题,它描述了如何从同一个类中的另一个 ctor 调用你的 ctor,以避免使用 init 方法或类似的方法。现在我尝试用这样的代码做同样的事情:

返回文章页面

class Tokenizer
{
public:
Tokenizer();
Tokenizer(std::stringstream *lines);
virtual ~Tokenizer() {};
private:
std::stringstream *lines;
};

Cpp:

Tokenizer::Tokenizer()
: expected('=')
{
}


Tokenizer::Tokenizer(std::stringstream *lines)
: Tokenizer(),
lines(lines)
{
}

但这给了我一个错误: 在构造函数‘ config: : Tokenizer: : Tokenizer (std: : stringstream *)’中: /path/Tokenizer.cpp:14:20: error: mem-initializer for ‘config::Tokenizer::lines’ follows constructor delegation I've tried moving the Tokenizer() part first and last in the list but that didn't help.

这背后的原因是什么,我应该如何修复它?我试过用 this->lines = lines;lines(lines)移动到身体上,它工作得很好。但我真的希望能够使用初始化列表。

44294 次浏览

When you delegate the member initialization to another constructor, there is an assumption that the other constructor initializes the object 彻底的, including all members (i.e. including the lines member in your example). You can't therefore initialize any of the members again.

标准中的相关引用是(强调我的) :

(12.6.2.6) mem-initializer-list 可以使用任何表示构造函数的类本身的类或声明类型委托给构造函数类的另一个构造函数。如果 mem-initializer-id 指定构造函数的类 它应该是唯一的 mem- 初始化程序; 构造函数是一个委托构造函数,由该构造函数选择的构造函数是目标构造函数。[...]

You can work-around this by defining the version of the constructor that takes arguments 第一:

Tokenizer::Tokenizer(std::stringstream *lines)
: lines(lines)
{
}

然后使用委托定义缺省构造函数:

Tokenizer::Tokenizer()
: Tokenizer(nullptr)
{
}

作为一般规则,您应该完全指定接受最多参数的构造函数版本,然后从其他版本进行委托(在委托中使用所需的默认值作为参数)。