多態

多態在C++中是通過虛函數實現的,通過前面的模型【參見“有重寫的單繼承”】知道,如果類中有虛函數,編譯器就會自動生成一個虛函數表,對象中包含一個指向虛函數表的指針,能夠實現多態的關鍵在於:虛函數時允許被派生類重寫的,在虛函數表中,派生類函數對覆蓋基類函數。初次之外,還必須通過指針或引用調用方法才行,將派生類對象賦給基類對象。

wKioL1fIGVSiUANmAAAerJGMzkg291.png-wh_50

上面兩個類,基類派生類中都包含兩個方法

void print() const;
virtual void print_virtual() const;

這兩個方法的區別就是一個是普通成員函數,一個是虛函數,編寫代碼如下

void test_polmorphisn()
{
Base b;
Derived d;

b = d;
b.print();
b.print_virtual();

Base *p;
p = &d;
p->print();
p->print_virtual();
}

根據模型推測,只有p->print_virtual()才實現了動態,其他3調用基類方法,原因如下:

1)b.print();b,print_virtual();不能實現多態是因爲通過基類對象調用,而非指針或引用所以不能實現多態。

2)p->print();不能實現多態是因爲,print函數沒有生命爲虛函數,派生類中也定義了print函數知識隱藏了基類的print函數。

爲什麼析構函數設爲虛函數是不要的?

析構函數應當都是虛函數,除非明確該類不做基類(不被其他類繼承),基類的析構函數聲明爲虛函數,這樣做是爲了確保釋放派生類對象時,按照正確的順序調用析構函數。

從C++對象模型可以知道,如果析構函數不定義爲虛函數,那麼派生類就不會重寫基類的析構函數,在有多態行爲的時候,派生類的析構函數不會被調用到。

例如,通過new一個派生類對象,賦給基類指針,然後delete基類指針

void test_vitual_destructor()
{
Base *p = new Derived();
delete p;
}

如果基類函數不是析構函數

wKioL1fIHaexEGrzAAAD06ojXos045.png

注意,缺少派生類的析構函數調用,把析構函數聲明爲虛函數,調用就正常了

wKioL1fIHePxet6sAAADmUkNJzs794.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章