本來是准備在工廠模式中順便整理。但粗略瀏覽了,內容還是很多,需要單獨開一篇。
一、什么是多態性?
多態性可以概括為“一個接口,多種方法”。
多態與非多態的區別在於“成員函數調用地址的早綁定和晚綁定”。“早綁定”在編譯期就可以確定函數的調用地址,是靜態的;“晚綁定”在運行時才能確定函數的調用地址,是動態的。
多態的作用是什么呢?在面向對象的編程中,“封裝”使得代碼模塊化;“繼承”可以擴展以存在的代碼;“多態”使得接口重用。
二、多態性的c++實現:虛函數
聲明基類的指針,該指針指向子類的對象。調用相應的虛函數時,可以根據子類的不同而調用不同的函數實現。因此有多態的三個條件:
1)基類指針
2)指向子類對象
3)調用的是虛函數
特殊的,對於強制類型轉換,可以將子類對象的指針強制轉化為基類對象的指針,
1)當以基類對象的指針調用非虛函數時,仍然調用子類的函數實現
2)當以基類對象的指針調用虛函數時,由於動態綁定,調用的是基類的函數的實現
三、虛函數的底層實現
虛函數(Virtual Function)通過一張虛函數表(Virtual Table)來實現,主是要一個類的虛函數的地址表。在有虛函數的類的實例中保存了指向虛函數表的指針,並且指針存儲的位置通常是實例的首地址。
1、虛基類
函數地址在表中的排列順序同函數的聲明順序。
2、當子類函數覆蓋父類虛函數
覆蓋的函數f()位於父類虛函數f()的位置,其他函數排列不變。
四、虛函數實例
class base { public: virtual void f() {cout << "in base::f()" << endl;} //虛函數 void g() { cout << "in base::g()" << endl;} //非虛函數 }; class derive: public base { public: virtual void f() {cout << "in derive::f()" << endl;} //覆蓋 void g() {cout << "in derive::g()" << endl;} //重載 }; int main(int argc, char **argv) { base *b = new derive(); //基類指針指向派生類的實例 b->f(); //虛函數 動態綁定 調用派生類的函數 b->g(); //非虛函數 靜態編譯 調用基類的函數 }