C++ 使用委托构造函数时的成员初始化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12190051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Member initialization while using delegated constructor
提问by lfxgroove
I've started trying out the C++11 standard and i found thisquestion which describes how to call your ctor from another ctor in the same class to avoid having a init method or the like. Now i'm trying the same thing with code that looks like this:
我已经开始尝试 C++11 标准,我发现这个问题描述了如何从同一类中的另一个 ctor 调用您的 ctor 以避免使用 init 方法等。现在我正在尝试使用如下所示的代码做同样的事情:
hpp:
马力:
class Tokenizer
{
public:
Tokenizer();
Tokenizer(std::stringstream *lines);
virtual ~Tokenizer() {};
private:
std::stringstream *lines;
};
cpp:
cp:
Tokenizer::Tokenizer()
: expected('=')
{
}
Tokenizer::Tokenizer(std::stringstream *lines)
: Tokenizer(),
lines(lines)
{
}
But this is giving me the error:
In constructor ‘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.
但这给了我错误:
In constructor ‘config::Tokenizer::Tokenizer(std::stringstream*)':
/path/Tokenizer.cpp:14:20: error: mem-initializer for ‘config::Tokenizer::lines' follows constructor delegation
我尝试在列表中首先和最后移动 Tokenizer() 部分,但这没有帮助。
What's the reason behind this and how should i fix it? I've tried moving the lines(lines)
to the body with this->lines = lines;
instead and it works fine. But i would really like to be able to use the initializer list.
这背后的原因是什么,我应该如何解决?我试过将lines(lines)
移到 body 上this->lines = lines;
,但效果很好。但我真的希望能够使用初始化列表。
回答by jogojapan
When you delegate the member initialization to another constructor, there is an assumption that the other constructor initializes the object completely, including all members (i.e. including the lines
member in your example). You can't therefore initialize any of the members again.
当您将成员初始化委托给另一个构造函数时,假设另一个构造函数完全初始化对象,包括所有成员(即,包括lines
示例中的成员)。因此您不能再次初始化任何成员。
The relevant quote from the Standard is (emphasis mine):
该标准的相关引用是(强调我的):
(§12.6.2/6) A mem-initializer-list can delegate to another constructor of the constructor's class using any class-or-decltype that denotes the constructor's class itself. If a mem-initializer-id designates the constructor's class, it shall be the only mem-initializer; the constructor is a delegating constructor, and the constructor selected by the is the target constructor. [...]
(§12.6.2/6) mem-initializer-list 可以使用任何表示构造函数类本身的 class-or-decltype 委托给构造函数类的另一个构造函数。如果 mem-initializer-id 指定构造函数的类,则它应该是唯一的 mem-initializer;构造函数是委托构造函数,被选中的构造函数是目标构造函数。[...]
You can work-around this by defining the version of the constructor that takes arguments first:
您可以通过定义首先采用参数的构造函数的版本来解决此问题:
Tokenizer::Tokenizer(std::stringstream *lines)
: lines(lines)
{
}
and then define the default constructor using delegation:
然后使用委托定义默认构造函数:
Tokenizer::Tokenizer()
: Tokenizer(nullptr)
{
}
As a general rule, you should fully specify that version of the constructor that takes the largest number of arguments, and then delegate from the other versions (using the desired default values as arguments in the delegation).
作为一般规则,您应该完全指定采用最多参数的构造函数版本,然后从其他版本进行委托(使用所需的默认值作为委托中的参数)。