多態在C++中是經過虛函數實現的,經過前面的模型【參見「有重寫的單繼承」】知道,若是類中有虛函數,編譯器就會自動生成一個虛函數表,對象中包含一個指向虛函數表的指針,可以實現多態的關鍵在於:虛函數時容許被派生類重寫的,在虛函數表中,派生類函數對覆蓋基類函數。初次以外,還必須經過指針或引用調用方法才行,將派生類對象賦給基類對象。ide
上面兩個類,基類派生類中都包含兩個方法函數
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; }
若是基類函數不是析構函數
注意,缺乏派生類的析構函數調用,把析構函數聲明爲虛函數,調用就正常了