父類指針拓轻、子類指針
-
父類指針可以指向子類的對象
image.png
多態(tài)
- 同一操作作用于不同對象,可以有不同的解釋行剂,產(chǎn)生不同的執(zhí)行結(jié)果航徙。
- 默認(rèn)情況下,c++只會根據(jù)指針類型調(diào)用對應(yīng)的函數(shù),不存在多態(tài)。
Animal *p = new Cat();
//并不會調(diào)用 cat 的函數(shù)厂置,而是調(diào)用animal的函數(shù)菩掏。
c++通過虛函數(shù)實現(xiàn)多態(tài)
- virtual聲明虛函數(shù)
- 父類如果寫了虛函數(shù),那么子類對應(yīng)函數(shù)也是虛函數(shù),不需要寫virtual.
class Animal{
public:
virtual void run(){
cout<<"animal run"<<endl;
}
class Cat{
void run(){
cout<<"cat run"<<endl;
}
}
重寫(override)
- 子類函數(shù)對父類函數(shù)的覆寫。
多態(tài)的要素
- 子類重寫父類的成員函數(shù)(override)
- 父類指針指向子類對象
- 利用父類指針調(diào)用(重寫的)成員函數(shù)
虛函數(shù)與普通函數(shù)的匯編區(qū)別
虛
speak()是普通函數(shù)昵济,run()是虛函數(shù)智绸。
虛函數(shù)原理
使用sizeof計算虛函數(shù)占用內(nèi)存大小,發(fā)現(xiàn)它比普通函數(shù)大了4個字節(jié)(x86),是因為其中有一個指向虛表的指針。
虛表
-
虛表存儲著最終需要調(diào)用的虛函數(shù)指針
image.png
image.png
結(jié)合上表访忿,就能理解匯編代碼
image.png
image.png
image.png
調(diào)用父類成員函數(shù)
父類::函數(shù)名
animal::speak()瞧栗;
虛析構(gòu)函數(shù)
- 如果存在父類指針指向子類對象的情況,應(yīng)該將析構(gòu)函數(shù)聲明為虛函數(shù)(虛析構(gòu)函數(shù))
- delete父類指針時海铆,才會調(diào)用子類的析構(gòu)函數(shù)迹恐,保證析構(gòu)的完整性
純虛函數(shù)
- 沒有函數(shù)體且定義為0的的虛函數(shù),用來定義接口規(guī)范
virtual void run() = 0;
抽象類
- 含有純虛函數(shù)的類,不可以實例化
- 如果父類是抽象類卧斟,而子類沒有完全重寫純虛函數(shù)殴边,子類依然是抽象類
多繼承
- c++允許一個子類有多個父類,但是不建議使用,增加復(fù)雜性珍语。
- 如果子類繼承的多個父類有虛函數(shù),則子類會有多個虛表锤岸。
虛繼承
虛繼承能解決菱形繼承的問題(變量冗余)
image.png
image.png
image.png