我已经开始尝试C ++ 11标准了,我发现了this问题,该问题描述了如何从同一个类中的另一个ctor调用你的ctor以避免使用init方法等。现在我正在使用看起来像这样的代码尝试相同的事情:
HPP:
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)
{
}
但是这给了我错误:
In constructor ‘config::Tokenizer::Tokenizer(std::stringstream*)’:
/path/Tokenizer.cpp:14:20: error: mem-initializer for ‘config::Tokenizer::lines’ follows constructor delegation
我已经尝试先将Tokenizer()部分移动到列表中,但最终却没有帮助。
这背后的原因是什么,我该如何解决?我尝试用lines(lines)
将this->lines = lines;
移到身体上,但效果很好。但我真的希望能够使用初始化列表。
提前致谢!
答案 0 :(得分:103)
当您将成员初始化委托给另一个构造函数时,假设另一个构造函数初始化对象 ,包括所有成员(即在您的示例中包括lines
成员) 。因此,您无法再次初始化任何成员。
标准的相关引用是(强调我的):
(§12.6.2/ 6)mem-initializer-list可以使用表示构造函数类本身的任何class-or-decltype委托给构造函数类的另一个构造函数。如果mem-initializer-id指定构造函数的类,它应该是唯一的mem-initializer ;构造函数是委托构造函数,由它选择的构造函数是目标构造函数。 [...]
您可以通过定义首先接受参数 的构造函数的版本来解决此问题:
Tokenizer::Tokenizer(std::stringstream *lines)
: lines(lines)
{
}
然后使用delegation定义默认构造函数:
Tokenizer::Tokenizer()
: Tokenizer(nullptr)
{
}
作为一般规则,您应该完全指定获取最大数量参数的构造函数的版本,然后从其他版本委派(使用所需的默认值作为委托中的参数)。