多態

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

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();不能實現多態是由於經過基類對象調用,而非指針或引用因此不能實現多態。blog

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

爲何析構函數設爲虛函數是不要的?get

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

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

例如,經過new一個派生類對象,賦給基類指針,而後delete基類指針io

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

若是基類函數不是析構函數

wKioL1fIHaexEGrzAAAD06ojXos045.png

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

wKioL1fIHePxet6sAAADmUkNJzs794.png

相關文章
相關標籤/搜索