OOD(Object Oritented Design)
- Inheritance 繼承
- 表示 is-a
- public, private, protected Inheritance
- 子類繼承父類的所有數(shù)據(jù)成員
- 子類對函數(shù)繼承是繼承調(diào)用權(quán)
- Composition 復(fù)合/組合
- 表示 has-a
- Delegation 委托
- Composition by reference 也稱為引用復(fù)合/組合(不是真正的has-a,而是has-a-pointer which point to a object)
- 實際上component是指針,但約定俗成稱為引用復(fù)合。component指針指向另一個類,需要的時候可以通過指針調(diào)用(委托)另一個類
- Handle/Body。Handle是接口,Body是實現(xiàn)。這是一種松耦合的思想
- pimpl(pointer to implication)
- reference counting 就是一種Delegation的實現(xiàn)。另外,當(dāng)一個對象想通過reference改變指向的對象時,就需要實現(xiàn)copy-on-write(寫時復(fù)制)
- Composition by reference 也稱為引用復(fù)合/組合(不是真正的has-a,而是has-a-pointer which point to a object)
UML關(guān)系圖
+ public
- private
# private
_ static
Inheritance with virtual functions
non-virtual function:不希望derived class overwrite
-
virtual function
- 希望derived class overwrite。
- 已有默認(rèn)定義。
-
pure virtual function
- 一定要 derived class overwrite。
- 沒有默認(rèn)定義。(其實可以有定義)
class Shape {
public:
virtual void draw() const = 0;
virtual void error(const std::string& msg);
int objectID() const;
};
Inheritance, Composition的構(gòu)造和析構(gòu)順序
-
Inheritance
- 構(gòu)造由內(nèi)到外:super class constructor ==> derived class constructor
- 析構(gòu)由外到內(nèi):derived class destructor ==> super class destructor
- super class destructor must be virtual, otherwise occurs undefined behavior
-
Composition
- 構(gòu)造由內(nèi)到外:component default constructor ==> derived class constructor
- 析構(gòu)由外而內(nèi):derived class destructor ==> component destructor
-
Inheritance + Composition
- 構(gòu)造由內(nèi)到外,先父類再組合:super class constructor ==> component default constructor ==> derived class constructor
- 析構(gòu)由外到內(nèi),先組合在父類:derived class destructor ==> component destructor ==> super class destructor
Inheritance,Composition,Delegation 和設(shè)計模式
Template Method 模板方法/函數(shù)
- Inheritance with virtual functions 的實現(xiàn),晚綁定
- MFC, 通過Template Method思想實現(xiàn)的Application Framework
Adapter 適配器模式
Composition的實現(xiàn)
Observer 觀察者模式
Delegation + Inheritance
Composite 組合模式
Delegation + Inheritance
Prototype
Delegation + Inheritance
現(xiàn)在要創(chuàng)建未來的class對象,使得Prototype能看到新創(chuàng)建的對象
類型轉(zhuǎn)換與繼承
派生類向基類的類型轉(zhuǎn)換
- 從派生類到基類的類型轉(zhuǎn)換只對指針或者引用類型有效
Quote item; // 基類對象
Bulk_quote bulk; // 派生類對象
Quote *p = &item; // p指向Quote對象
p = &bulk; // p指向bulk的Quote部分
Quote &r = bulk; // r綁定到bulk的Quote部分
- (非指針或引用)派生類對象也可以拷貝、移動或者賦值給一個基類對象。但由于是調(diào)用基類的拷貝控制成員,所以只能處理派生類的基類部分,派生部分會被切掉(sliced down)
Bulk_quote bulk; // 派生類對象
Quote item(bulk); // 使用Quote::Quote(const Quote&)構(gòu)造函數(shù)
item = bulk; // 使用Quote::operator=(const Quote&)賦值操作符
- 不存在基類向派生類的隱式轉(zhuǎn)換
Bulk_quote bulk; // 派生類對象
Quote *itemP = &bulk; // itemP的動態(tài)類型是Bulk_quote
// 即使itemP指針綁定的動態(tài)類型是Bulk_quote(派生類),但itemP的靜態(tài)類型是Quote(基類)
// 編譯器只能通過檢查指針或引用的靜態(tài)類型來判斷該轉(zhuǎn)換是否合法
Bulk_quote *bulkP = itemP; // 錯誤,不能將基類轉(zhuǎn)換成派生類
靜態(tài)類型 vs. 動態(tài)類型
-
存在條件
- 當(dāng)使用存在繼承關(guān)系的類型時
- 且當(dāng)變量或者表達(dá)式是引用或指針時
- 存在靜態(tài)類型(static type)和動態(tài)類型(dynamic type)
靜態(tài)類型是在編譯時已知的,是變量聲明的類型
動態(tài)類型是在運行時才可知的,是表示內(nèi)存中的對象的類型
動態(tài)綁定(dynamic binding/ run-time binding), 多態(tài)性, 虛函數(shù),虛函數(shù)表
-
動態(tài)綁定:函數(shù)運行時選擇函數(shù)版本
- 和overload區(qū)分。overload是指同一個類里,同名函數(shù)通過參數(shù)不同來確定調(diào)用哪個函數(shù)。注意和返回值無關(guān),和繼承無關(guān),和virtual無關(guān)
-
當(dāng)且僅當(dāng)基類通過指針或者引用指向派生類類型,且調(diào)用的是虛函數(shù)時,才能實現(xiàn)動態(tài)綁定(會在運行時解析該調(diào)用)。但這時還不算實現(xiàn)了多態(tài)性,還需要派生類重寫override了虛函數(shù),這是才會調(diào)用動態(tài)類型的虛函數(shù),實現(xiàn)多態(tài)性- 不滿足以上的任何一個條件,都無法實現(xiàn)動態(tài)綁定(多態(tài)性),調(diào)用的都是本身的函數(shù)(編譯時綁定的函數(shù))
- 調(diào)用非虛函數(shù),普通對象調(diào)用函數(shù)都是在編譯時綁定了調(diào)用函數(shù)的版本。
多態(tài)性:父類的指針有“多種形態(tài)”。簡而言之就是用父類的指針指向其子類的實例,然后通過父類的指針調(diào)用實際子類的成員函數(shù)
-
虛函數(shù)的作用主要是實現(xiàn)了多態(tài)的機(jī)制
- 虛函數(shù)(Virtual Function)是通過一張?zhí)摵瘮?shù)表(Virtual Table)來實現(xiàn)的
顯式類型轉(zhuǎn)換
C++風(fēng)格的類型轉(zhuǎn)換提供了4種類型轉(zhuǎn)換操作符來應(yīng)對不同場合的應(yīng)用
cast-name<type>(expression)
- const_cast
- 去const屬性
- dynamic_cast
- 轉(zhuǎn)換的安全檢查將在運行時執(zhí)行
- 多態(tài)類之間的類型轉(zhuǎn)換用daynamic_cast
- static_cast
- 類似于C風(fēng)格的強(qiáng)制轉(zhuǎn)換。無條件轉(zhuǎn)換
- 強(qiáng)制覆蓋編譯器的檢查工作
- 基本類型轉(zhuǎn)換用static_cast
- reinterpret_cast
- 不同類型的指針類型轉(zhuǎn)換用reinterpret_cast