C++:45---多型
一、多型介紹
面向物件的核心思想是多型性,其含義是“多種形式”
概念:在子類覆蓋了父類函式的情況下,用父類的指標(或引用)呼叫子類物件,或者通過父類指標呼叫覆蓋函式的時候(動態繫結),實際上呼叫的是子類的覆蓋版本,這種現象叫做多型
注意事項:
只有用父類的指標(或引用)呼叫子類物件多型才會產生,非指標/引用不會產生多型
且只有用父類的指標(或引用)呼叫虛擬函式才會產生多型,呼叫非虛擬函式不會產生多型效果
執行時解析:
當我們使用基類的引用或指標呼叫基類中定義的一個虛擬函式時,我們並不知道該函式真正作用的物件是什麼型別,因為它可能是一個基類的物件也可能是一個派生類的物件
如果該函式是虛擬函式,則直到執行時才會決定到底執行哪個版本。非虛擬函式的呼叫在編譯時進行繫結的,類似的,通過物件進行的函式(虛擬函式或非虛擬函式)呼叫也在編譯時繫結
二、多型的條件
父子類之間有覆蓋關係
基類必須通過引用或指標指向子類,然後再呼叫虛擬函式,此時就可以實現多型
三、演示案例
class A{public://虛擬函式virtual void show()const { cout << "A1 "; }void show2()const { cout << "A2\n"; }};class B :public A{public://虛擬函式void show()const { cout << "B1 "; }void show2()const { cout << "B2\n"; }};void printfShow(A const& data){data.show();data.show2();}int main(){A a;B b;printfShow(a);printfShow(b);return 0;}
執行結果:
結果分析:
①printfShow(a):因為傳入的是A類物件,所以呼叫的是A類中的show()和show2()方法,這個沒什麼稀奇的,看下面
②printfShow(b):傳入的是B類物件,而B類是A的派生類
所以呼叫show()時,由於show是虛擬函式,所以此時對於show的呼叫取決於引用所指的物件型別(此處為B,所以呼叫B的show函式,這就是動態繫結與多型的效果)
呼叫show2()時,因為show2()不是虛擬函式,所以不會有多型的效果,此時對函式的呼叫取決於引用的型別(A型別),所以呼叫A類的show2()方法這個原理就是前面介紹“派生類向基類轉換”的文章的知識點.
四、virtual函式的預設引數值是靜態繫結的
五、多型的實現方式(面試)
1.必須有繼承關係
2.父子類之間有重寫(覆蓋)
3.父類的指標指向於子類,或父類的引用指向於子類
4.通過父類的指標或引用呼叫成員方法,會實現不同的效果