2010-02-18 180 views
111

是否可以使用子类的构造函数的初始化列表初始化在父类中声明为受保护的数据成员?我无法让它工作。我可以解决这个问题,但如果我不必这样做会很好。使用初始化列表(C++)初始化父级的受保护成员

一些示例代码:

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

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

当我尝试,编译器告诉我:“类‘儿童’没有名为‘东西’任何领域”。是这样的可能吗?如果是这样,语法是什么?

非常感谢!

回答

103

这是不可能的你描述的方式。你必须添加一个构造函数(可以被保护)到基类来转发它。喜欢的东西:

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

    std::string something; 
} 

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

这正是解决办法我已经拿出。至少现在我不必担心它是否可以完成。 :) – Stephen 2010-02-18 17:47:37

11

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

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

51

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

从的C++ 0x草案:

12.6.2初始化碱和构件

名称中的MEM-初始化-ID是 在的范围查找 构造函数的类,如果在该范围内找不到 ,则在包含构造函数的 定义的 作用域中查找。 [注意:如果 构造函数的类包含一个构件 具有相同名称作为直接或 虚基类的类的,一个 MEM-初始化-ID命名构件 或基类和单个 标识符组成的指给班级成员。 隐藏的 基类的meminitializer-id可以使用 限定名称指定。末端注] 除非 MEM-初始化ID名称的 构造函数的类,非静态数据的构造函数的类的 成员或类的 直接或虚拟的基础上, 的MEM-初始化是非法的构造。

注:强调我的。

+2

感谢您指点我的“为什么”。总体感觉。我已经离开C++太久了...... :) – Stephen 2010-02-18 17:48:46

0

也许你可以使用关键字尝试以这种方式“使用”

class Parent 
{ 

protected: 
std::string something; 
}; 

class Child : public Parent 
{ 

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