在C++的類中有許多種繼承方式,而我們在軟件設(shè)計和編寫代碼時用得最多的就是public繼承,我們很少接觸到private繼承。但是我們在設(shè)計時真的有思考過什么時候應(yīng)該用public繼承,什么時候不該使用public繼承,什么時候應(yīng)該想想那些經(jīng)常被我們遺忘的知識,讓我們從它們被遺忘的角落里重拾它的光芒。例如private繼承。
As we all know,public繼承是塑模出一種is-a關(guān)系。什么是is-a的關(guān)系呢?Effective C++這樣描述:如果你令class D以public形繼承class B,那么每一個類型為D的對象同時也是一個類型為B的對象,反之不成立。意思是B比D表現(xiàn)出更一般化的概念,而D比B表現(xiàn)出更特殊化的概念。你主張“B對象可派上用場的地方,D對象一樣可以派上用場”,因為每一個D對象都是一種(是一個)B對象。反之如果你需要一個D對象,B對象無法效勞。
還有就是我們喜歡用的virtual函數(shù),即運行動態(tài)也是建立在public繼承之上的。
在我剛學(xué)C++時,只知道private繼承,使繼承而來的成員(public成員和protected成員)都成為private,至于它有沒有什么更深一層的意義和作用就沒有去思考了,只是理想當(dāng)然地把它認(rèn)為是不想這些成員被它的以后的子類繼承。那private繼承到底意味著什么呢?
先看看下面的代碼:
class Person{...};
class Student:private Person{...};
void eat(const Person &p);
Person p;
Student s;
eat(p);//正確
eat(s);//錯誤
再看看Effective C++的說法:
如果classes之間的繼承關(guān)系是private,編譯器不會自動將一個deirved class對象轉(zhuǎn)換為一個base class對象。
private繼承意味著implemented-in-terms-of(根據(jù)某物實現(xiàn)出)。如果你讓class D以private繼承class B,你的用意是為了采用class B內(nèi)已經(jīng)備妥的某些特性,不是因為B對象和D對象存在有任何觀念上的關(guān)系。private繼承純粹是一種實現(xiàn)技術(shù),意味著只有實現(xiàn)部分被繼承,接口部分應(yīng)該略去。如果D以private形式繼承B,意思是D對象根據(jù)B對象實現(xiàn)而得,private繼承在軟件設(shè)計層面上沒有意義,其意義只及于軟件實現(xiàn)層面。
private有點has-a的感覺。它的意義與復(fù)合的意義相同。那我們的問題又產(chǎn)生了,什么時候用復(fù)合什么時候用private繼承?答案很簡單,盡可能使用復(fù)合。除了以下的2種情況:
1、private繼承通常比復(fù)合的級別低。但是當(dāng)derived class需要訪問protected base class的成員,或需要重新定義繼承而來的virtual函數(shù)時,就要用private繼承。
2、private繼承可以造成empty class最優(yōu)化。