2011-04-17 40 views
-1

我試圖解決以下測驗。標有藍色的答案是正確的,標有紅色的答案是錯誤的。據我,如果任何一個類的派生保護然後一路下行的內容不能被訪問的層次,但我不知道爲什麼的答案是錯誤的。問題解決中的一個繼承測驗

這裏是測驗: enter image description here 對於X,Y和Z,下列組合是什麼類型的成員的類A和B都在類直接訪問D.Fill一個檢查可訪問性和非可訪問性。 下面是我的解決辦法, enter image description here

紅色的答案是不正確。下面是我的解釋,

private/public/private: 
As D is privately derived from C, then it should not have an access to any of the A, B or C. 

public/public/private: 
As D is privately derived from C, then it should not have an access to any of the A, B or C. 

下面是從低於該檢查結果的答案代碼,

#define X public 
#define Y private 
#define Z private 

class A { 
public: int public_a; 
protected: int protected_a; 
private: int private_a; 
}; 

class B : X A { 
public: int public_b; 
protected: int protected_b; 
private: int private_b; 
}; 

class C : Y B { 
}; 

class D : Z C { 
public: 
    void test_inheritance_visibility() 
    { 
     int foo; 
     foo = public_a; 
     foo = protected_a; 
     foo = private_a; 
     foo = public_b; 
     foo = protected_b; 
     foo = private_b; 
    } 
}; 

希望我已經解釋過clearly.Please幫我在清理我的concept.Thanks

+1

這個問題很難理解,你能說清楚嗎?基本規範中的訪問說明符控制派生到基本轉換的可訪問性。如果'A'具有公共成員,那麼無論繼承路徑如何,都可以從'D'成員訪問它們。無法訪問的是將'this'轉換爲_cv_-'A *',如果它是需要訪問的'this'的成員。沒有看到示例代碼,不清楚蜱和十字會代表什麼。 – 2011-04-17 10:19:11

+0

前三列用於A類,其他三列用於B類。支票和交叉表示D類對A和B類的訪問。 – 2011-04-17 10:43:54

+0

@Charles:如果A具有公共成員並且B是私人繼承的C和D是否相互關聯,那麼D如何訪問A的私有成員?當A被私下繼承時,它的所有公共成員都變爲私有的 – 2011-04-17 11:20:44

回答

4

下面的代碼提供了一種方法來測試作業問題的繼承規則。

#define inherit_A public  A 
#define inherit_B private B 
#define inherit_C private C 

class A { 
public: int public_a; 
protected: int protected_a; 
private: int private_a; 
}; 

class B : inherit_A { 
public: int public_b; 
protected: int protected_b; 
private: int private_b; 
}; 

class C : inherit_B { 
}; 

class D : inherit_C { 
public: 
    void test_inheritance_visibility() 
    { 
     int foo; 
     foo = public_a; 
     foo = protected_a; 
     foo = private_a; 
     foo = public_b; 
     foo = protected_b; 
     foo = private_b; 
    } 
}; 

剪切和粘貼上面的代碼到一個名爲,比如說,test.cpp文件,然後嘗試編譯它。編譯器報告的錯誤消息將指示表中一行的繼承可見性規則。然後在文件的開頭更改#define,並重新編譯它以檢查表的另一行。

當我這樣做(在Linux上使用G ++編譯器),編譯器錯誤,表示自己是不正確爲表的第二行,但正確該表的倒數第二行。

我不主張理解這些測試結果。特別是,我認爲你是正確的這兩個表中的行(我沒有打擾檢查沒有紅色標記的行)。我對Als的答案的閱讀也表明,對於那些有紅色標記的線條,你應該是正確的。

無論如何,至少你現在有一些簡單的代碼,你可以帶給你的老師讓你有更深入的關於繼承可視性的討論。

+1

對於那個簡單的測試用例。 :)雖然定義會小心,因爲你也有一個'int x'小寫。 ;) – Xeo 2011-04-17 10:55:46

+0

@Xeo,感謝您的反饋。我編輯了代碼,將'x'重命名爲'foo'。 – 2011-04-17 11:02:38

+0

嘿,我寧願將定義更改爲'#define inherit_A public A'等等。但是那也沒關係。 :) – Xeo 2011-04-17 11:06:21

2

訪問Specifers和繼承規則可以簡單地概括爲:

  1. 公有繼承
    Base所有Public members成爲Derived classPublic members
    Base所有Protected members成爲Derived class
  2. 保護繼承Protected members
    Base Class所有Public & Protected members成爲Protected membersDerived class
  3. 私有繼承
    Base Class所有public & protected members成爲Derived ClassPrivate members
  4. Private MembersBase class是繼承,但never accessibleDerived Class

您可能想要參考一個previous answer,其中解釋了上述概念與示例。

至於答案你問的具體問題,這個問題本身也不是很清楚,所以無法明確回答。如果你能澄清這個問題就越能回答的問題,或者是能夠理解的概念,並提到的鏈接,然後我相信你將能夠自己解決的問題。

+0

感謝您的解釋。我已經解釋了更多。你能幫我嗎? – 2011-04-17 11:21:46

3

讓我們把它捲起來: 首先,Z是什麼都沒有關係。如果您的D繼承自C類,則無論是public,private還是protected,D都可以獲得完整的接口。只有D的「孩子」纔會擔心這一點。

並且publicprotected成員之間並沒有真正的區別,只要能夠訪問子孫就可以了。 private部分與人類一樣,都是私密的,不是界面的一部分,只是非常接近friends而且永遠不會與後代分享!

對於B類在d無障礙只有Y是有趣: C:Y B

Ÿ告訴你什麼C GET的後裔:民營:沒什麼,保護:接口齊全,市民:接口齊全。

其中在第3行

第7行解決您的問題是一種奇怪的,因爲它似乎是完全正確的。你確定這些十字架不屬於那裏嗎?

要訪問A在D中的接口,X和Y必須是寬容的(保護或公共的)。

+0

所有的藍色答案是真實的,紅色的是錯誤的:)感謝您的解釋:) – 2011-04-17 11:35:50

+0

+1爲您解釋表中的第3行。當我使用我在答案中提供的測試代碼時,Linux上的G ++ 4.4.1編譯器同意你的分析,表中第3行的紅色標記是合理的,但不是第7行中的紅色標記。法赫德說他的編譯器的結果就像教師標記的那樣。因此,我們有兩個不同意繼承可見性規則的編譯器。我懷疑某處有編譯器錯誤。 – 2011-04-17 12:34:52

+0

鑑於第7行顯然是公共/公共/私人,那麼第3行的解釋也適用於第7行,唯一的區別是,現在還有A成員可以由於公衆對B的訪問而被訪問。也許你可以更新你的答案以反映更新 – ChrisWue 2011-04-18 06:25:23