1. 程式人生 > >多型的現象及本質剖析(一)

多型的現象及本質剖析(一)

多型的現象,同樣的呼叫語句有著不同的表現形態。

#include <iostream>
using namespace std;
class animal
{
public:
    virtual void func() = 0;//純虛擬函式
protected:
private:
    //char *voice = "我是annimal怎麼叫?";
};
class duck:public animal
{
public:
    virtual void func()//純虛擬函式重寫
    {
        cout << voice << endl;
    }
protected
: private: char *voice = "我是鴨子,嘎嘎嘎"; }; class cat:public animal { public: virtual void func()//純虛擬函式重寫 { cout << voice << endl; } protected: private: char *voice = "我是小貓,喵喵喵"; }; //框架 void cry(animal *p)//賦值相容性原則,可傳遞子類指標 { p->func(); } int main() { duck d1; cat c1; cry(&d1);//執行效果:我是鴨子,嘎嘎嘎
cry(&c1);//執行效果:我是小貓,喵喵喵 system("pause"); return 0; }

上例中同樣是呼叫cry()函式,不同的物件傳入,可以呼叫各自物件中的方法,產生不同的現象。這個現象便是多型。
從上述程式碼中可以總結出多型產生的條件有三個:
1、父類子類繼承關係。
2、(純)虛擬函式重寫。
3、父類指標(引用)指向子類物件。

virtual關鍵字,告訴編譯器這個函式要支援多型;不要根據指標型別判斷如何呼叫;而是要根據指標所指向的實際物件型別來判斷如何呼叫。

C++多型實現原理:
當類中宣告(純)虛擬函式時,編譯器會在類中生成一個虛擬函式表
虛擬函式表是一個儲存類成員函式指標的資料結構
虛擬函式表是由編譯器自動生成與維護的
virtual成員函式會被編譯器放入虛擬函式表中
存在虛擬函式時,每個物件中都有一個指向虛擬函式表的指標(vptr指標)
這裡寫圖片描述


拿上述程式碼duck類來說,編譯的時候,編譯器會自動為duck加上一個VPTR指標,duck當執行d1類初始化的時候,編譯器就會自動建立一個d1的虛擬函式表,存放d1的func函式指標,而VPTR也會指向這個虛擬函式表。