2010-01-16 120 views
1

我已經基於this問題私人與公共繼承

在部分問題 http://www.parashift.com/c%2B%2B-faq-lite/private-inheritance.html#faq-24.3 提到以下幾點:

一個合法的,長期使用的私有繼承是當你想要構建一個在類Wilma中使用代碼的類Fred,並且來自Wilma類的代碼需要從您的新類Fred中調用成員函數。在這種情況下,弗雷德在威爾瑪稱非虛擬化,而威爾瑪本身調用(通常是純虛擬),這被弗雷德覆蓋。這對於構圖來說會更難。

但是,我想知道爲什麼使用公有繼承不會達到同樣的效果。 即下面的一段C#代碼做同樣的事情..

class Wilma 
{ 
    protected void FredCallsWilma() { 
     Console.Write("Fred Calls Wilma ;"); 
     WilmaCallsFred(); 
    } 

    protected virtual void WilmaCallsFred() {} 
} 

class Fred : Wilma 
{ 
    public void barney(){ 
     Console.Write("barney;"); 
     FredCallsWilma(); 
    } 

    protected override void WilmaCallsFred(){ 
     Console.Write("Wilma Calls Fred ;"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args){ 
     Fred f1 = new Fred(); 
     f1.barney(); 
    } 
} 

它打印

巴尼;弗雷德呼喚威爾瑪; Wilma呼叫Fred

那麼,在C++ faq lite中引用的私有繼承有什麼特別之處。不會用公有繼承來代替私有繼承工作就可以很好地實現這個結果嗎?

回答

3

公共繼承使基類可以被外部世界訪問。例如,一個指向派生類的指針可以被轉換(隱含地,不會少於)一個指向基類的指針。考慮從鏈接列表派生的堆棧。您通常不希望有人隱式地將您的數組轉換爲其基本鏈接列表,這將允許他們執行堆棧不允許的操作,例如在中間插入或刪除項目。

歸因於私有繼承的通常含義是「以......實現」 - 這意味着我們通常不希望允許外部世界/用戶看到/瞭解/關心這個類有一個基礎的事實類。公共繼承應該遵循Liskov替代規則,該規則規定派生類可以在公共基類被調用的任何地方被替換。對於私有繼承,我們並不是說派生類可以替代基類。

公有繼承是一種設計技術。它的目的是讓你正在編寫的代碼被其他代碼所使用,這些代碼已經知道如何使用基類提供的接口。

私有繼承是一種實現技術。其目的僅僅是通過使用基類的代碼來簡化你的實現。

1

是的,你是對的。引用的段落只是引用了子類可以訪問隱藏類的私有成員,以及可能的用例。

有些人錯誤地認爲你不能訪問繼承類的私有成員。

+0

你說「錯誤地認爲你不能訪問繼承類的私有成員」。但是,在任何類型的繼承(public,private或protected)中,基類的私有成員不能由派生類訪問。不是嗎? – Santhosh 2010-01-16 07:36:01

+0

如果一個類嵌套在另一個類中,則內部類可以從外部類繼承,並且還可以訪問其公共成員(允許獨立於繼承的訪問)。 – supercat 2011-01-01 17:41:15