2013-01-19 67 views
8

那麼有足夠的關於這個問題的信息。例如,這條線程對我來說很清楚:Difference between private, public, and protected inheritanceC++爲什麼要使用公共,私有或受保護的繼承?

除了一點;爲什麼它有用?

+0

對於一個回答你的問題的一半,看到http://stackoverflow.com/questions/656224/when-should-i-use-c-private-inheritance – NPE

+0

此外,HTTP:// stackoverflow.com/questions/374399/why-do-we-actually-need-private-or-protected-inheritance-in-c – NPE

回答

8

使用公有繼承反映是一種關係。這是繼承的主要用途,尤其是與虛擬功能相結合。它允許重新使用接口,而不僅僅是舊代碼的新代碼,還可以重新使用舊代碼的新代碼! (因爲在運行時虛擬功能調度)。

在特殊情況下,使用私有繼承以反映是實現合條件方面的關係。這是一個通常被濫用的模式,通常可以通過組合(具有可能的基類作爲數據成員)達到相同的目標。另一個缺點是你可以很容易地擁有相同基類的多重繼承(刪除兩次或更多),從而導致所謂的Diamond Problem

避免使用受保護的繼承,它表明您的類接口是依賴於客戶端(派生類與世界)。通常這是由於具有多重責任的類,因此暗示重構爲單獨的類是適當的。

+0

「_twice或更多removed_」你是什麼意思? – curiousguy

+0

@curiousguy我的意思是兩個類之間的繼承層數。 'D:B'一旦被移除,'D1:B','D2:B'和'E:D1,D2'就是所謂的鑽石,其中一個類繼承了兩個類,每個類繼承自同一個類。 'E'在這裏從'B'兩次移除。 – TemplateRex

1

全部關於數據封裝

http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)

Encapsulation concept

這是很好的保護從其他類的類 '內部' 的數據。優點包括:

  • 其他類要經過已知的適當的訪問機制(例如使用的方法)來訪問你的類,並且不能與你的類的內部猴子直接左右(因此可能把你的班級分成一些未知和破碎的狀態)
  • 你可以改變你的類的內部工作,並且知道其他類不會打破,結果
  • 減少一類接觸的可見外緣點,使你的類簡單的使用和理解

Hav使用protected而不是private的選項也使您的代碼更容易通過子類化進行擴展。

0

此問題的答案涉及類接口和數據封裝,而不是語言功能。

受保護和私有繼承的用例相當有限,因爲通常有其他更好地解決問題的選項(例如使用組合而不是繼承)。但是,有時候您必然會從某種類型繼承必須(例如與第三方庫的接口),但您會強烈要求(因爲與您類的用戶界面相關的原因)隱藏大多數成員從新類型的用戶繼承基類。一個典型的場景是,當你需要你的類型使某個類的成員函數在內部使用時,但是如果它是從類外部調用的話,它將會破壞你新類型的邏輯。

在這些情況下,您需要使用privateprotected繼承(取決於接口應同樣受到限制,以進一步派生類與否。

請記住,但是,這一切只是約(強烈地)暗示你的班級的用戶應該如何使用它,你正在調整它的公共接口來隱藏在其基類中公開的某些功能,這嚴格來說不會阻止人們訪問這些成員,因爲任何人都可以仍然會將指向派生類的指針指向基指針,並以此方式到達「隱藏」資源。

0

Private:只能從類函數,構造函數和析構函數訪問類的私有成員。將使用您的課程的客戶將無法訪問它們。所以,如果你正在實現一個列表類,並且你想跟蹤列表的大小,那麼你應該有一個私有變量(例如listSizeP)。您這樣做是因爲您不希望客戶端能夠在不插入元素的情況下修改列表的大小。

公開:公共成員也可以由客戶端訪問。在上面提到的列表示例中,功能如inserterase應該是公開的。

受保護:受保護的類的成員(如私有成員)只能從類函數訪問,但它們也可以由此類繼承的類訪問(實際上取決於派生類繼承方法如果它不是公有繼承,那麼派生類就不能訪問基類的私有成員,這就是爲什麼最常見的繼承方式是公有繼承)。例如:

#include <iostream> 

using namespace std; 

class Base { 
public: 
    int num; 
public: 
    Base(int x=0) : num(x) {} 
}; 

class Derived : public Base { 
public: 
    Derived(int x=0) : Base(x) {} 
    void tell() { cout << "num: " << num << endl; } 
}; 

int main() { 
    Derived D(4); 
    D.tell(); // would cause error if num was private 
    return 0; 
} 
相關問題