1 面向?qū)ο蟮娜汛蟮?-復(fù)合璃吧、委托和繼承
1.1復(fù)合(Composition)
1.1.1 定義
復(fù)合表示的是has-a的關(guān)系楷掉。在實(shí)現(xiàn)類中包含有復(fù)合類的一個(gè)完整實(shí)體吵瞻,是一種類與類之間強(qiáng)的關(guān)系运嗜。在UML圖示中用實(shí)心菱形表示仲翎。代碼示例如下:
class A;
class B{A a;}
1.1.2 復(fù)合關(guān)系下的構(gòu)造和析構(gòu)
- 構(gòu)造由內(nèi)而外
復(fù)合關(guān)系下的構(gòu)造函數(shù)痹扇,先執(zhí)行復(fù)合類的默認(rèn)構(gòu)造函數(shù),在執(zhí)行自身的構(gòu)造函數(shù)體谭确。如果不希望調(diào)用復(fù)合類的默認(rèn)構(gòu)造函數(shù)或者復(fù)合類沒(méi)有默認(rèn)構(gòu)造函數(shù)帘营,則要在初始化列表中做顯示的初始化。如下:
class A{
int x;
public:
A(int _x):x(_x){}
}
class B{
A a;
int _y;
public:
B(int x,int y):a(x),_y(y){}
};
- 析構(gòu)由外而內(nèi)
復(fù)合關(guān)系下的構(gòu)造函數(shù)逐哈,先執(zhí)行自身的析構(gòu)函數(shù),在執(zhí)行復(fù)合類的析構(gòu)函數(shù)问顷。
1.2 委托(Delegation) Composition by reference
委托表示的也是has-a的關(guān)系昂秃。在實(shí)現(xiàn)類中包含有委托類的一個(gè)引用,是類與類之間比較弱的關(guān)系杜窄,在UML圖示中用空心棱形表示肠骆。代碼示例如下:
class A;
class B{
A *p;
}
1.3 繼承(Inheritance)
1.3.1 定義
類通過(guò)繼承聯(lián)系在一起構(gòu)成一種層次結(jié)構(gòu)。在這種層次結(jié)構(gòu)中塞耕,頂層的類叫做父類或基類蚀腿;其他類則直接或間接的從基類繼承而來(lái),這些繼承而來(lái)的類稱為派生類或子類扫外。在UML圖示中用空心三角形表示莉钙。
在C++中,繼承有三種實(shí)現(xiàn)方式筛谚,公有繼承(public)磁玉,保護(hù)繼承(protected)和私有(private)繼承。通過(guò)在類派生列表中指定驾讲。派生列表的形式為class drived_class:public A,protected B,private C
蚊伞。類派生列表中的訪問(wèn)說(shuō)明符并不影響直接子類訪問(wèn)父類的成員,而是限制子類的客戶訪問(wèn)基類的成員吮铭。也就是說(shuō)时迫,當(dāng)使用Private繼承基類C時(shí),子類依然可以訪問(wèn)父類C的公有成員和保護(hù)成員谓晌,但是子類的子類及子類的調(diào)用者則無(wú)法訪問(wèn)基類C中的所有成員掠拳,包括C中的公有成員。因?yàn)樵眩宇惏碢rivate從父類繼承成員時(shí)碳想,將父類所有的成員都繼承為自己的Private成員烧董,因此類的用戶就無(wú)法調(diào)用。
注意:一般情況下胧奔,都是用Public繼承逊移,Protected和private很少用。
1.3.2 繼承關(guān)系下的構(gòu)造和析構(gòu)
- 構(gòu)造由內(nèi)而外
繼承關(guān)系下的構(gòu)造函數(shù)龙填,先執(zhí)行父類的默認(rèn)構(gòu)造函數(shù)胳泉,在執(zhí)行自身的構(gòu)造函數(shù)體。如果不希望調(diào)用復(fù)合類的默認(rèn)構(gòu)造函數(shù)或者復(fù)合類沒(méi)有默認(rèn)構(gòu)造函數(shù)岩遗,則要在初始化列表中做顯示的初始化扇商。如下:
class A{
int x;
public:
A(int _x):x(_x){}
}
class B:public A{
A a;
int _y;
public:
B(int x,int y):a(x),_y(y){}
};
- 析構(gòu)由外而內(nèi)
繼承關(guān)系下的構(gòu)造函數(shù),先執(zhí)行自身的析構(gòu)函數(shù)宿礁,在執(zhí)行父類的析構(gòu)函數(shù)案铺。
2 虛函數(shù)與多態(tài)
2.1 虛函數(shù)
2.1.1 虛函數(shù)定義
對(duì)于某些函數(shù),如果基類希望子類實(shí)現(xiàn)符合各自需求的版本梆靖,那就可以把這些函數(shù)聲明為虛函數(shù)控汉。子類必須在其內(nèi)部實(shí)現(xiàn)中隊(duì)重新定義的虛函數(shù)進(jìn)行聲明。聲明虛函數(shù)時(shí),需要在函數(shù)聲明的前面添加virtual,如virtual void a_virt_func();
。
2.1.2 虛函數(shù)使用場(chǎng)景
- non-virtual函數(shù)
你不希望子類重新定義(override)父類的函數(shù)重慢。 - virtual函數(shù)
你希望子類重新定義(override)它,但是希望它有默認(rèn)定義街佑。 - pure virtual函數(shù)
你希望子類重新定義(override)它,但是對(duì)他沒(méi)有默認(rèn)的定義捍靠。
2.2 多態(tài)
多態(tài)是OOP的核心思想沐旨,意思為“多種形式”。我們把具有繼承關(guān)系的多個(gè)類型稱作多態(tài)類型剂公,因?yàn)槲覀兡苁褂眠@些類型的“多種形式”而無(wú)須在意他們之間的差異希俩。在C++中,引用和指針的動(dòng)態(tài)類型和靜態(tài)類型的不一致正是實(shí)現(xiàn)這一機(jī)制的關(guān)鍵纲辽。
參考資料:
1.GeekBand課件
2.cpp primer 5th edition