在《C++箴言:確保公開繼續模擬“is-a”》一文中論述了 C++ 將 public inheritance(公有繼續)視為一個 is-a 關系。 當給定一個 hierarchy(繼續體系),其中有一個 class Student 從一個 class Person 公有繼續,當為一個函數調用的成功而有必要時,需要將 Students 隱式轉型為 Persons,它通過向編譯器展示來做到這一點。用 PRivate inheritance(私有繼續)代替 public inheritance(公有繼續)把這個例子的一部分重做一下是值得的:
class Person { ... }; class Student: private Person { ... }; // inheritance is now private
void eat(const Person p); // anyone can eat
void study(const Student s); // only students study
Person p; // p is a Person Student s; // s is a Student
eat(p); // fine, p is a Person
eat(s); // error! a Student isn't a Person
很明顯,private inheritance(私有繼續)不意味著 is-a。那么它意味著什么呢?
“喂!”你說:“在我們得到它的含義之前,我們先看看它的行為。private inheritance(私有繼續)有怎樣的行為呢?”好吧,支配 private inheritance(私有繼續)的第一個規則你只能從動作中看到:與 public inheritance(公有繼續)對照,假如 classes(類)之間的 inheritance relationship(繼續關系)是 private(私有)的,編譯器通常不會將一個 derived class object(派生類對象)(諸如 Student)轉型為一個 base class object(基類對象)(諸如 Person)。這就是為什么為 object(對象)s 調用 eat 會失敗。第二個規則是從一個 private base class(私有基類)繼續的 members(成員)會成為 derived class(派生類)的 private members(私有成員),即使它們在 base class(基類)中是 protected(保護)的或 public(公有)的。
假如 D 從 B 私有繼續,它就意味著 D objects are implemented in terms of B objects(D 對象是根據 B 對象實現的),沒有更多了。private inheritance(私有繼續)在 software design(軟件設計)期間沒有任何意義,只在 software implementation(軟件實現)期間才有。 private inheritance(私有繼續)意味著 is-implemented-in-terms-of(是根據……實現的)的事實有一點混亂,正如《通過composition模擬“has-a”》一文中所指出的 composition(復合)也有同樣的含義。你怎么預先在它們之間做出選擇呢?答案很簡單:只要你能就用 composition(復合),只有在絕對必要的時候才用 private inheritance(私有繼續)。什么時候是絕對必要呢?主要是當 protected members(保護成員)和/或 virtual functions(虛擬函數)摻和進來的時候,另外還有一種與空間相關的極端情況會使天平向 private inheritance(私有繼續)傾斜。我們稍后再來操心這種極端情況。
我們決定修改 Widget class 以持續跟蹤每一個 member function(成員函數)被調用了多少次。在運行時,我們可以周期性地檢查這一信息,與每一個 Widget 的這個值相伴的可能還有我們覺得有用的其它數據。為了進行這項工作,我們需要設立某種類型的 timer(計時器),以便在到達收集用法統計的時間時我們可以知道。
在《C++箴言:確保公開繼續模擬“is-a”》一文中論述了 C++ 將 public inheritance(公有繼續)視為一個 is-a 關系。當給定一個 hierarchy(繼續體系),其中有一個 class Student 從一個 class Person 公有繼續,當為一個函數調用的成功而有必要時,需要將 Students 隱式轉型為 Persons,它通過向編譯器展示來做到這一點。用 private inheritance(私有繼續)代替 public inheritance(公有繼續)把這個例子的一部分重做一下是值得的:
class Person { ... }; class Student: private Person { ... }; // inheritance is now private
void eat(const Person p); // anyone can eat
void study(const Student s); // only students study
Person p; // p is a Person Student s; // s is a Student
eat(p); // fine, p is a Person
eat(s); // error! a Student isn't a Person
很明顯,private inheritance(私有繼續)不意味著 is-a。那么它意味著什么呢?
“喂!”你說:“在我們得到它的含義之前,我們先看看它的行為。private inheritance(私有繼續)有怎樣的行為呢?”好吧,支配 private inheritance(私有繼續)的第一個規則你只能從動作中看到:與 public inheritance(公有繼續)對照,假如 classes(類)之間的 inheritance relationship(繼續關系)是 private(私有)的,編譯器通常不會將一個 derived class object(派生類對象)(諸如 Student)轉型為一個 base class object(基類對象)(諸如 Person)。這就是為什么為 object(對象)s 調用 eat 會失敗。第二個規則是從一個 private base class(私有基類)繼續的 members(成員)會成為 derived class(派生類)的 private members(私有成員),即使它們在 base class(基類)中是 protected(保護)的或 public(公有)的。
假如 D 從 B 私有繼續,它就意味著 D objects are implemented in terms of B objects(D 對象是根據 B 對象實現的),沒有更多了。private inheritance(私有繼續)在 software design(軟件設計)期間沒有任何意義,只在 software implementation(軟件實現)期間才有。 private inheritance(私有繼續)意味著 is-implemented-in-terms-of(是根據……實現的)的事實有一點混亂,正如《通過composition模擬“has-a”》一文中所指出的 composition(復合)也有同樣的含義。你怎么預先在它們之間做出選擇呢?答案很簡單:只要你能就用 composition(復合),只有在絕對必要的時候才用 private inheritance(私有繼續)。什么時候是絕對必要呢?主要是當 protected members(保護成員)和/或 virtual functions(虛擬函數)摻和進來的時候,另外還有一種與空間相關的極端情況會使天平向 private inheritance(私有繼續)傾斜。我們稍后再來操心這種極端情況。
我們決定修改 Widget class 以持續跟蹤每一個 member function(成員函數)被調用了多少次。在運行時,我們可以周期性地檢查這一信息,與每一個 Widget 的這個值相伴的可能還有我們覺得有用的其它數據。為了進行這項工作,我們需要設立某種類型的 timer(計時器),以便在到達收集用法統計的時間時我們可以知道。