2010-02-18 179 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!"; 
} 
};