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

时间:2010-02-18 17:29:31

标签: c++ inheritance constructor initialization-list

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

一些示例代码:

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

class Child : public Parent
{
private:
    Child() : something("Hello, World!")
    {
    }
};

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

非常感谢!

4 个答案:

答案 0 :(得分:112)

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

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

    std::string something;
}

class Child : public Parent
{
private:
    Child() : Parent("Hello, World!")
    {
    }
}

答案 1 :(得分:61)

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

来自C ++ 0x草案:

  

12.6.2初始化基础和成员

     

2 mem-initializer-id中的名称是   抬头望去了   构造函数的类,如果没有找到   在那个范围内,被查到了   包含构造函数的范围   定义。 [注意:如果   构造函数的类包含一个成员   与直接或同名的同名   类的虚拟基类,a   mem-initializer-id命名成员   或基类,由单个组成   identifier指的是类成员。   隐藏的meminitializer-id   可以使用a指定基类   合格的名字。 - 注意事项] 除非   mem-initializer-id命名   构造函数的类,非静态数据   构造函数类的成员或者   该类的直接或虚拟基础,   mem-initializer格式不正确。

     

注意:强调我的。

答案 2 :(得分:12)

无法在派生类构造函数初始化列表中初始化父类的成员。它们是受保护的,公共的还是其他任何事都无关紧要。

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

答案 3 :(得分:0)

也许您可以使用关键字“使用”

以这种方式尝试
class Parent
{

protected:
std::string something;
};

class Child : public Parent
{

private:
using Parent::something;
Child()
{
    something="Hello, World!";
}
};