2013-08-27 69 views
1

我有一個基類/父類:人類繼承錯誤:個人會員

和兩個子類/子類:球員,教練

這是基類人看起來頭像:

class Person 
{ 
    public: 
     Person(string name); 
     Person(); 
     virtual ~Person(); 
     string getName(); 
     void setName(string name); 
     virtual void printSpec() const = 0; 

    private: 
     string name; 
}; 

我試圖編譯和運行,它開始抱怨這一點:

include\Person.h||In constructor 'Coach::Coach(std::string, std::string)':| 
include\Person.h|19|error: 'std::string Person::name' is private| 
\src\Coach.cpp|5|error: within this context| 
||=== Build finished: 2 errors, 0 warnings ===| 

,並指出這一點:

private: 
    string name; 

進一出的兩個構造子類「教練」的背景:

Coach::Coach(string name, string responsibility): Person(name){ 
    this->name = name; 
    this->responsibility = responsibility; 
} 

但是,它並沒有對此做出了同樣的抱怨非常「Player」類構造函數中的相同行,只在「Coach」類的構造函數中聲明「字符串名稱是私有成員」。

我查了一些其他人的解決方案,試圖保護而不是私人,試圖改變變量的名稱,但沒有用。

什麼給?

+1

如果您已經在Coach構造函數中調用Person(name),爲什麼需要設置this-> name在所有?我認爲Person :: Person會照顧那個嗎? 在任何情況下,受保護的範圍都應該起作用。 – Vivek

+0

獲取一本[關於C++的正派書籍](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 'Player :: name'是私人的。如果你希望派生類具有成員級訪問權(在這種情況下沒有理由,但多數民衆贊成在另一個問題)它需要*保護*或*公共*或*朋友* -ed(後者非常不尋常的派生類)。 – WhozCraig

+0

你如何申報Coach課程? (不要忘記在那裏使用公開的詞) – doctorlove

回答

4

A private成員不能被派生類訪問。

的解決方案是使用成員初始化列表做到這一點:

Coach::Coach(string name, string responsibility): Person(name){ 
    //           ^^^^^^^^^^^^ 
    //      Initialize the name through the base class constructor 
    this->responsibility = responsibility; 
} 

因爲Person基類,並有一個構造函數的名稱,你可以做就這樣。您無需訪問派生類中的name成員。


另一種解決方案可以是設置這個構件protected第一溶液仍然是較好)。

class Person 
{ 
    public: 
     Person(string name); 
     Person(); 
     virtual ~Person(); 
     string getName(); 
     void setName(string name); 
     virtual void printSpec() const = 0; 

    protected: 
// ^^^^^^^^^ 
     string name; 
}; 

你可以看看here,繼承部分講的是access-type。


不回答這個問題,但一些好的做法,我建議你到你string傳遞參數作爲參考const。這是一個better practice

Coach::Coach(const string& name, const string& responsibility): Person(name){ 
    //  ^^^^^  ^  ^^^^^  ^
    this->responsibility = responsibility; 
} 
+0

'Coach' ** **是從'Person'派生的,所以構造函數是正確的方法。將'name'更改爲** protected ** ** **。構造函數可以初始化成員,如果需要,可以使用'setName'成員函數稍後進行設置。 –

+0

@PeteBecker你是對的,我編輯我的帖子,使其更合適。感謝您指出了這一點。 –

1

將「私有」更改爲「受保護」私有意味着系統的其他部分(包括派生類)不能訪問該成員。

+0

**不要**將其更改爲受保護。 Person的構造函數初始化'name','setName'成員函數根據需要更改它。這裏沒有理由使用'protected'。 –

+0

同意。我只是解決了「爲什麼編譯器會產生錯誤」。使用訪問器方法比保護更好(在這種情況下)。 –

2

name是在基類私有的,所以你不能從派生類訪問它。
假設Coach從Person公開派生出來,您可以使該成員變量受到保護,但幸運的是,構造函數接受一個名稱,所以您不需要直接從派生類訪問它。您可以使用初始化列表,因此不需要設置兩次

Coach::Coach(string name, string responsibility) 
        : Person(name){ 
       // ^^^^^^^^^^^^ 
       // Sends name to Person's constructor 
    this->responsibility = responsibility; 
} 
+0

'教練'不需要公開派生**;只要'Person'是一個基類,它就可以在初始化程序列表中初始化。 –

+0

真的很抱歉,我會編輯我失去的想法 – doctorlove