淺談C++多型
阿新 • • 發佈:2018-12-11
面向物件的程式設計都有封裝,繼承和多型三大特性,前兩個特性在之前的部落格中已經提到,這篇主要講關於C++多型問題。
何為多型?
簡單的說,就是一句話:允許將子類型別的指標(引用)賦值給父類型別的指標(引用)。
舉個例子,當我們在定義兩個類,一個Person類作為父類,在乘坐高鐵時購買二等座,Boss是Person的派生類,乘車購買一等座,而且他們的購票成員函式名字相同,如以下程式碼:
class Person { public: void Dis(void) { cout << "Second-class seat" << endl; } }; class Boss :public Person { public: void Dis(void) { cout << "First-class seat" << endl; } };
在寫一個Fun函式傳入兩個型別的例項化物件對其成員函式進行呼叫時,我們將Fun的引數型別僅設定為Person的引用,看看能不能實現多型,即自動區分兩個例項化物件,對其買票做出正確的輸出
#include <iostream> using namespace std; class Person { public: void Dis(void) { cout << "Second-class seat" << endl; } }; class Boss :public Person { public: void Dis(void) { cout << "First-class seat" << endl; } }; void Fun(Person& p) { p.Dis(); } int main() { Person p; Fun(p); Boss b; Fun(b); return 0; }
執行起來後發現程式沒有對其進行區分...
那麼將要引入多型的形成條件:
- 虛擬成員函式的重寫
- 呼叫虛擬函式函式的引數型別為父類指標/引用
虛擬成員函式的重寫到底是說明概念呢?我們之前都瞭解到過函式的過載,函式的重定義,下邊歸納一下這三個概念:
函式的過載:在同一作用域當中,函式名相同,引數不同構成過載
函式的重寫(覆蓋規則):子類成員的虛擬函式與父類成員的虛擬成員函式完全一樣
函式的重定義(同名隱藏規則):子類成員函式與父類成員函式名相同
我們根據規則將程式碼進行改動
#include <iostream> using namespace std; class Person { public: virtual void Dis(void) { cout << "Second-class seat" << endl; } }; class Boss :public Person { public: virtual void Dis(void) { cout << "First-class seat" << endl; } }; void Fun(Person& p) { p.Dis(); } int main() { Person p; Fun(p); Boss b; Fun(b); return 0; }
這時候就產生了我們的預期效果,也就是利用例項化出來的物件就可以直接用父類指標或者引用函式進行操作,會實現自動找到各自的成員虛擬函式。
下一篇部落格將會對C++多型原理以及虛表的概念進行分析,請在部落格目錄中翻閱瀏覽