OOD(Object Oritented Design)
- Inheritance 繼承
- 表示 is-a
- public, private, protected Inheritance
- 子類(lèi)繼承父類(lèi)的所有數(shù)據(jù)成員
- 子類(lèi)對(duì)函數(shù)繼承是繼承調(diào)用權(quán)
- Composition 復(fù)合/組合
- 表示 has-a
- Delegation 委托
- Composition by reference 也稱(chēng)為引用復(fù)合/組合(不是真正的has-a,而是has-a-pointer which point to a object)
- 實(shí)際上component是指針抛计,但約定俗成稱(chēng)為引用復(fù)合吹截。component指針指向另一個(gè)類(lèi),需要的時(shí)候可以通過(guò)指針調(diào)用(委托)另一個(gè)類(lèi)
- Handle/Body晨逝。Handle是接口懦铺,Body是實(shí)現(xiàn)。這是一種松耦合的思想
- pimpl(pointer to implication)
- reference counting 就是一種Delegation的實(shí)現(xiàn)昏翰。另外,當(dāng)一個(gè)對(duì)象想通過(guò)reference改變指向的對(duì)象時(shí)浸踩,就需要實(shí)現(xiàn)copy-on-write(寫(xiě)時(shí)復(fù)制)
- Composition by reference 也稱(chēng)為引用復(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。
- 沒(méi)有默認(rèn)定義怕犁。(其實(shí)可以有定義)
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)到外奏甫,先父類(lèi)再組合:super class constructor ==> component default constructor ==> derived class constructor
- 析構(gòu)由外到內(nèi)凌受,先組合在父類(lèi):derived class destructor ==> component destructor ==> super class destructor
Inheritance,Composition,Delegation 和設(shè)計(jì)模式
Template Method 模板方法/函數(shù)
- Inheritance with virtual functions 的實(shí)現(xiàn)胜蛉,晚綁定
- MFC, 通過(guò)Template Method思想實(shí)現(xiàn)的Application Framework
Adapter 適配器模式
Composition的實(shí)現(xiàn)
Observer 觀察者模式
Delegation + Inheritance
Composite 組合模式
Delegation + Inheritance
Prototype
Delegation + Inheritance
現(xiàn)在要?jiǎng)?chuàng)建未來(lái)的class對(duì)象,使得Prototype能看到新創(chuàng)建的對(duì)象
類(lèi)型轉(zhuǎn)換與繼承
派生類(lèi)向基類(lèi)的類(lèi)型轉(zhuǎn)換
- 從派生類(lèi)到基類(lèi)的類(lèi)型轉(zhuǎn)換只對(duì)指針或者引用類(lèi)型有效
Quote item; // 基類(lèi)對(duì)象
Bulk_quote bulk; // 派生類(lèi)對(duì)象
Quote *p = &item; // p指向Quote對(duì)象
p = &bulk; // p指向bulk的Quote部分
Quote &r = bulk; // r綁定到bulk的Quote部分
- (非指針或引用)派生類(lèi)對(duì)象也可以拷貝领突、移動(dòng)或者賦值給一個(gè)基類(lèi)對(duì)象案怯。但由于是調(diào)用基類(lèi)的拷貝控制成員殴泰,所以只能處理派生類(lèi)的基類(lèi)部分浮驳,派生部分會(huì)被切掉(sliced down)
Bulk_quote bulk; // 派生類(lèi)對(duì)象
Quote item(bulk); // 使用Quote::Quote(const Quote&)構(gòu)造函數(shù)
item = bulk; // 使用Quote::operator=(const Quote&)賦值操作符
- 不存在基類(lèi)向派生類(lèi)的隱式轉(zhuǎn)換
Bulk_quote bulk; // 派生類(lèi)對(duì)象
Quote *itemP = &bulk; // itemP的動(dòng)態(tài)類(lèi)型是Bulk_quote
// 即使itemP指針綁定的動(dòng)態(tài)類(lèi)型是Bulk_quote(派生類(lèi))至会,但itemP的靜態(tài)類(lèi)型是Quote(基類(lèi))
// 編譯器只能通過(guò)檢查指針或引用的靜態(tài)類(lèi)型來(lái)判斷該轉(zhuǎn)換是否合法
Bulk_quote *bulkP = itemP; // 錯(cuò)誤,不能將基類(lèi)轉(zhuǎn)換成派生類(lèi)
靜態(tài)類(lèi)型 vs. 動(dòng)態(tài)類(lèi)型
-
存在條件
- 當(dāng)使用存在繼承關(guān)系的類(lèi)型時(shí)
- 且當(dāng)變量或者表達(dá)式是引用或指針時(shí)
- 存在靜態(tài)類(lèi)型(static type)和動(dòng)態(tài)類(lèi)型(dynamic type)
靜態(tài)類(lèi)型是在編譯時(shí)已知的宵蛀,是變量聲明的類(lèi)型
動(dòng)態(tài)類(lèi)型是在運(yùn)行時(shí)才可知的,是表示內(nèi)存中的對(duì)象的類(lèi)型
動(dòng)態(tài)綁定(dynamic binding/ run-time binding)凑懂, 多態(tài)性梧宫, 虛函數(shù),虛函數(shù)表
-
動(dòng)態(tài)綁定:函數(shù)運(yùn)行時(shí)選擇函數(shù)版本
- 和overload區(qū)分脓豪。overload是指同一個(gè)類(lèi)里扫夜,同名函數(shù)通過(guò)參數(shù)不同來(lái)確定調(diào)用哪個(gè)函數(shù)驰徊。注意和返回值無(wú)關(guān),和繼承無(wú)關(guān)望侈,和virtual無(wú)關(guān)
-
當(dāng)且僅當(dāng)
基類(lèi)
通過(guò)指針或者引用
指向派生類(lèi)類(lèi)型
勋桶,且調(diào)用的是虛函數(shù)
時(shí)例驹,才能實(shí)現(xiàn)動(dòng)態(tài)綁定(會(huì)在運(yùn)行時(shí)解析該調(diào)用)。但這時(shí)還不算實(shí)現(xiàn)了多態(tài)性鹃锈,還需要派生類(lèi)重寫(xiě)override
了虛函數(shù)屎债,這是才會(huì)調(diào)用動(dòng)態(tài)類(lèi)型的虛函數(shù),實(shí)現(xiàn)多態(tài)性- 不滿(mǎn)足以上的任何一個(gè)條件盆驹,都無(wú)法實(shí)現(xiàn)動(dòng)態(tài)綁定(多態(tài)性)躯喇,調(diào)用的都是本身的函數(shù)(編譯時(shí)綁定的函數(shù))
- 調(diào)用非虛函數(shù)硝枉,普通對(duì)象調(diào)用函數(shù)都是在編譯時(shí)綁定了調(diào)用函數(shù)的版本倦微。
多態(tài)性:父類(lèi)的指針有“多種形態(tài)”欣福。簡(jiǎn)而言之就是用父類(lèi)的指針指向其子類(lèi)的實(shí)例,然后通過(guò)父類(lèi)的指針調(diào)用實(shí)際子類(lèi)的成員函數(shù)
-
虛函數(shù)的作用主要是實(shí)現(xiàn)了多態(tài)的機(jī)制
- 虛函數(shù)(Virtual Function)是通過(guò)一張?zhí)摵瘮?shù)表(Virtual Table)來(lái)實(shí)現(xiàn)的
顯式類(lèi)型轉(zhuǎn)換
C++風(fēng)格的類(lèi)型轉(zhuǎn)換提供了4種類(lèi)型轉(zhuǎn)換操作符來(lái)應(yīng)對(duì)不同場(chǎng)合的應(yīng)用
cast-name<type>(expression)
- const_cast
- 去const屬性
- dynamic_cast
- 轉(zhuǎn)換的安全檢查將在運(yùn)行時(shí)執(zhí)行
- 多態(tài)類(lèi)之間的類(lèi)型轉(zhuǎn)換用daynamic_cast
- static_cast
- 類(lèi)似于C風(fēng)格的強(qiáng)制轉(zhuǎn)換棕诵。無(wú)條件轉(zhuǎn)換
- 強(qiáng)制覆蓋編譯器的檢查工作
- 基本類(lèi)型轉(zhuǎn)換用static_cast
- reinterpret_cast
- 不同類(lèi)型的指針類(lèi)型轉(zhuǎn)換用reinterpret_cast