c++特別要點:多態性與虛函數


本來是准備在工廠模式中順便整理。但粗略瀏覽了,內容還是很多,需要單獨開一篇。

一、什么是多態性?

  多態性可以概括為“一個接口,多種方法”。
  多態與非多態的區別在於“成員函數調用地址的早綁定和晚綁定”。“早綁定”在編譯期就可以確定函數的調用地址,是靜態的;“晚綁定”在運行時才能確定函數的調用地址,是動態的。
  多態的作用是什么呢?在面向對象的編程中,“封裝”使得代碼模塊化;“繼承”可以擴展以存在的代碼;“多態”使得接口重用。

二、多態性的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(); //非虛函數 靜態編譯 調用基類的函數
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM