Inheritance and Object-Oriented Design 的最後 3 個概念,我們將進一步探討繼承的進階用法。下一篇文章則又到了中場小測驗時間,各位看官敬請期待吧!
在 C++ 中,composition 有兩種語意。在規劃 API 或維護大型系統時,區分這兩種用法非常重要。
Car
類別擁有一個 Engine
類別list
實作 set
「組合」比「繼承」更適合用於實作關係,可根據語意判斷適用的設計思維。
私有繼承不是「is-a」而是「is-implemented-in-terms-of」,因此編譯器不會將私有繼承的子類別視為父類別。再次以知識點 32 的 Student
為例:
class Student {
public:
int age;
string school;
string thesis;
void introduce() const {
// implement here...
}
};
類別 Yoyo
私有繼承自 Student
。若為公共繼承,編譯器在語意上會把 Yoyo
當作 Student
看待;私有繼承則表示 Yoyo
是透過 Student
來實作某些功能:
class Yoyo : private Student {
public:
int salary;
};
此時外部的類別 Yoyo
無法呼叫 introduce()
,因為 Yoyo
並不是 public Student
:
Yoyo y;
y.introduce(); // complie error here...
若只是想重複使用某個類別的功能,或覆寫其虛擬函式,可以使用私有繼承。但其主要用於實作階段。更推薦以「公共繼承」搭配「組合」的方式,降低耦合並保護介面。
多重繼承會帶來複雜性,應小心使用並避免成員衝突,例如「菱形繼承」會導致成員變數重複。解法是使用知識點 7 和 知識點 35 不斷提及的 virtual 做「虛擬繼承」,但需注意虛擬繼承會增加記憶體與執行的負擔。
多重繼承可用於:
::testing::Test