使用初始化列表(C++)初始化父的受保护成员

Ste*_*hen 128 c++ inheritance constructor initialization-list

是否可以使用子类的构造函数的初始化列表来初始化在父类中声明为protected的数据成员?我无法让它发挥作用.我可以解决它,但如果我不必这样做会很好.

一些示例代码:

class Parent
{
protected:
    std::string something;
};

class Child : public Parent
{
private:
    Child() : something("Hello, World!")
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

当我尝试这个时,编译器告诉我:"类'Child'没有任何名为'something'的字段".这样的事情可能吗?如果是这样,语法是什么?

非常感谢!

phi*_*red 121

你描述的方式是不可能的.您必须向基类添加构造函数(可以受到保护)以将其转发.就像是:

class Parent
{
protected:
    Parent( const std::string& something ) : something( something )
    {}

    std::string something;
}

class Child : public Parent
{
private:
    Child() : Parent("Hello, World!")
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这正是我已经提出的解决方法.至少现在我不必担心它是否可以完成.:) (2认同)

dir*_*tly 64

当编译器遇到初始化列表时,尚未形成派生类对象.直到那时才调用基类构造函数.只有在调用了基类构造函数之后something才会出现.因此问题.当您没有显式调用基类构造函数时,编译器会为您执行此操作(通过为基类生成适当的简单构造函数).这会导致something成员默认初始化.

来自C++ 0x草案:

12.6.2初始化基础和成员

2在构造函数的类的范围内查找mem-initializer-id中的名称,如果在该作用域中找不到,则在包含构造函数定义的作用域中查找.[注意:如果构造函数的类包含与该类的直接或虚拟基类同名的成员,则命名该成员或基类并由单个标识符组成的mem-initializer-id引用该类成员.可以使用限定名称指定隐藏基类的meminitializer-id.-end note] 除非mem-initializer-id命名构造函数的类,构造函数类的非静态数据成员或该类的直接或虚拟基础,否则mem-initializer是不正确的.

注意:强调我的.

  • 谢谢你指着我"为什么".完全有道理.我已经离开C++太久了...... :) (2认同)

AnT*_*AnT 12

无法在派生类构造函数初始化列表中初始化父类的成员.它们是受保护的,公共的还是其他任何东西并不重要.

在您的示例中,member somethingParent类的成员,这意味着它只能在类的构造函数初始化列表中初始化Parent.