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

时间:2012-08-30 04:46:03

标签: c++ gcc c++11 ctor-initializer

我已经开始尝试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;移到身体上,但效果很好。但我真的希望能够使用初始化列表。

提前致谢!

1 个答案:

答案 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)
{
}

作为一般规则,您应该完全指定获取最大数量参数的构造函数的版本,然后从其他版本委派(使用所需的默认值作为委托中的参数)。