2016-03-14 23 views
1

快速問題:我認爲成員初始化列表的行爲與使用'='的常規初始化相同(除了只能使用初始化列表定義的const成員),調用構造函數即將傳入的具有特定參數的待初始化對象,如我在下面的示例中(我將調用x的構造函數的值爲1)。但是就我個人而言,在簡單繼承的情況下,編譯器抱怨沒有看到我想用我的構造函數初始化的成員,儘管看到另一個用慣常的'='語法初始化:初始化程序列表未檢測到公開繼承的成員

#include <iostream> 
using namespace std; 

class A 
{ 
public: 

    int x; 
    int y; 
}; 

class B : public A 
{ 
public: 

    B() : x(1) 
    { 
     y = 2; 
    } 
}; 

int main() 
{ 
    return 0; 
} 

如果你運行上面的代碼,你會發現雖然y被檢測到沒有問題,但你的編譯器會說在'B():x(1)'行沒有這樣一個名爲'x'的成員。這是爲什麼?繼承是公開的,你會看到,沒有問題,爲什麼不是x?

+2

可能的重複[我如何初始化派生類構造函數中的基類成員變量?](http://stackoverflow.com/questions/7405740/how-可以在我初始化基類成員變量在派生類構造函數) –

回答

1

您不能從B類的初始化程序列表初始化x,因爲只有A類可以初始化其成員。

順便說一下,使數據成員公開並不是一個好主意。下面是你的代碼如何工作的一個例子:

#include <iostream> 
using namespace std; 

class A 
{ 
public: 
    A(int x, int y) : x(x), y(y) {} 
protected: 

    int x; 
    int y; 
}; 

class B : public A 
{ 
public: 

    B() : A(1, 5000) 
    { 
     y = 2; 
    } 
}; 

int main() 
{ 
    return 0; 
} 
+0

yup,我已經找到了解決方案之前看到你的文章,它下面,標記爲答案。謝謝您的幫助!是的,我知道數據應該幾乎永遠不會公開,只是出於例子的目的,我總是讓它們變成私有的,這就要求我也使用setter/getter,它只會讓代碼片段超出應有的長度。然而,在這種情況下,使他們受到保護將不需要setter/getter,所以是的,在這個例子中,我的權利,我是在懶惰之外的必要:) – Otringal

+0

@Otringal我沒有看到任何標記的答案。無論如何,你明白出了什麼問題,這是重要的。我也提出了你的問題,因爲它顯示了一些努力。 – gsamaras

+0

非常感謝!我已將你的答案重新標記爲「那個」,不知道爲什麼它第一次沒有粘住:/ – Otringal

0

我想我已經找到了答案:正在執行A類的構造函數時

我的對象已經被初始化一次,所以我不能在運行B的構造函數時重新初始化。將y重新賦值爲2是可以的,但重新初始化x時,會傳遞1,因爲它的構造函數參數是編譯器錯誤的原因。我錯過了什麼嗎?

+1

可能最好刪除這個並接受gsamaras答案 –