使用初始化列表(C++)初始化父级的受保护成员
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2290733/
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
Initialize parent's protected members with initialization list (C++)
提问by Stephen
Is it possible to use the initialization list of a child class' constructor to initialize data members declared as protected in the parent class? I can't get it to work. I can work around it, but it would be nice if I didn't have to.
是否可以使用子类的构造函数的初始化列表来初始化在父类中声明为受保护的数据成员?我无法让它工作。我可以解决它,但如果我不必这样做就好了。
Some sample code:
一些示例代码:
class Parent
{
protected:
std::string something;
};
class Child : public Parent
{
private:
Child() : something("Hello, World!")
{
}
};
When I try this, the compiler tells me: "class 'Child' does not have any field named 'something'". Is something like this possible? If so, what is the syntax?
当我尝试这个时,编译器告诉我:“类‘Child’没有任何名为‘something’的字段”。这样的事情可能吗?如果是这样,语法是什么?
Many thanks!
非常感谢!
采纳答案by philsquared
It is not possible in the way you describe. You'll have to add a constructor (could be protected) to the base class to forward it along. Something like:
按照你描述的方式是不可能的。您必须向基类添加一个构造函数(可以受保护)才能将其转发。就像是:
class Parent
{
protected:
Parent( const std::string& something ) : something( something )
{}
std::string something;
}
class Child : public Parent
{
private:
Child() : Parent("Hello, World!")
{
}
}
回答by dirkgently
When the compiler comes across the initializer list, the derived class object is yet to be formed. The base class constructor has not been called till then. Only after the base class constructor has been called, something
comes to being. Hence the problem. When you do not call the base class constructor explicitly, the compiler does that for you (by generating the appropriate trivial constructor for the base class). This causes the something
member to be default initialized.
当编译器遇到初始化列表时,派生类对象尚未形成。直到那时还没有调用基类构造函数。只有在调用基类构造函数之后,something
才会出现。因此问题来了。当您不显式调用基类构造函数时,编译器会为您执行此操作(通过为基类生成适当的普通构造函数)。这会导致something
成员被默认初始化。
From C++0x draft:
来自 C++0x 草案:
12.6.2 Initializing bases and members
2Names in a mem-initializer-id are looked up in the scope of the constructor's class and, if not found in that scope, are looked up in the scope containing the constructor's definition. [ Note: if the constructor's class contains a member with the same name as a direct or virtual base class of the class, a mem-initializer-id naming the member or base class and composed of a single identifier refers to the class member. A meminitializer- id for the hidden base class may be specified using a qualified name. —end note ] Unless the mem-initializer-id names the constructor's class, a non-static data member of the constructor's class or a direct or virtual base of that class, the mem-initializer is ill-formed.
Note: Emphasis mine.
12.6.2 初始化基和成员
2mem-initializer-id 中的名称在构造函数类的范围内查找,如果在该范围内找不到,则在包含构造函数定义的范围内查找。[注意:如果构造函数的类包含与类的直接或虚拟基类同名的成员,则命名成员或基类并由单个标识符组成的 mem-initializer-id 引用该类成员。可以使用限定名称指定隐藏基类的 meminitializer-id。—end note ]除非 mem-initializer-id 命名构造函数的类、构造函数类的非静态数据成员或该类的直接或虚拟基类,否则 mem-initializer 是格式错误的。
注意:强调我的。
回答by AnT
You can'tinitialize members of the parent class in the derived class constructor initialization list. It doesn't matter whether they are protected, public or anything else.
您不能在派生类构造函数初始化列表中初始化父类的成员。它们是受保护的、公开的还是其他任何东西都没有关系。
In your example, member something
is member of Parent
class, which means that it can only be initialized in the constructor initializer list of Parent
class.
在您的示例中,成员something
是Parent
类的成员,这意味着它只能在类的构造函数初始值设定项列表中进行初始化Parent
。
回答by AnT
Maybe you can try it in that way using the keyword "using"
也许您可以使用关键字“使用”以这种方式尝试
class Parent
{
protected:
std::string something;
};
class Child : public Parent
{
private:
using Parent::something;
Child()
{
something="Hello, World!";
}
};