用C來模擬實現多態?

如何用C來模擬實現多態?
要實現多態,首先咱們應充分了解多態的原理。 
C++是如何實現多態的?函數

在基類的函數前加上virtual關鍵字,在派生類中重寫該函數,運行時將會根據對象的實際類型來調用相應的函數。若是對象類型是派生類,就調用派生類的函數;若是對象類型是基類,就調用基類的函數。佈局

也就是說: 
若是類中包含了虛函數–>類對象大小+4個字節–>地址(虛表)–>虛函數集合(虛函數表) 
基類虛表:按照基類虛函數的聲明次序將其添加到基類的虛表中 
派生類: 
一、將基類虛表中內存拷貝一份 
二、若是派生類重寫基類中某個虛函數,用派生類本身的虛函數替換虛表中相同偏移量位置的基類虛函數 
三、將派生類本身的虛函數添加在虛表的最後測試

多態調用原理(條件知足): 
一、確認是否爲虛函數–>否(call) 
二、從對象的前四個字節取虛表地址–>虛函數地址 
三、傳參 
四、調用this

咱們能夠用結構體和函數指針實現,以下:.net

// 幾個基本的函數,對應抽象類中的虛函數
void foo1()
{
    printf("base foo1 \r\n");
}指針

void foo2(int i)
{對象

}blog

void foo3(int i, int j)
{內存

}it

// 虛表,包含了虛函數的指針
typedef struct Vtbl
{
    void(*pf1)();
    void(*pf2)(int);
    void(*pf3)(int, int);
}Vtbl;

// 類的虛表
Vtbl g_vtbl = { &foo1, &foo2, &foo3, };

// 基類,開始處是虛表指針,後面是結構成員。
typedef struct Base
{
    //Vtbl *pvtbl;
    void *pvtbl;
    int field1;
    int field2;
}Base;

// 構造函數
// 也是一個普通的成員函數,須要一個this指針
void InitBase(Base *p)
{
    p->pvtbl = &g_vtbl;
    p->field1 = 0x1234;
    p->field2 = 0x5678;
}

// 子類中的虛函數,重載了父類中的同類型函數
void Sfoo1()
{
    // 能夠考慮調用父類中的函數
    // foo1();
    printf("derive foo1 \r\n");
}

void Sfoo4(char *s)
{
    printf("hello %s\r\n", s);
}

// 子類中的虛表,由於內存佈局是同樣的
// 直接使用父類的
typedef struct SVtbl
{
    Vtbl vtbl;
    void(*pf4)(char *);
}SVtbl;

// 子類的虛表
SVtbl g_svtbl = { { &Sfoo1, &foo2, &foo3, }, &Sfoo4, };

// 某個子類,包含父類的內容
// 還有本身的成員
typedef struct Derive
{
    Base a;
    int field3;
}Derive;

// 構造函數
// 也是一個普通的成員函數,須要一個this指針
void InitDerive(Derive *p)
{
    InitBase((Base*)p);
    p->a.pvtbl = &g_svtbl;
    p->field3 = 0xabcd;
}

void TestPolymorphism(Base *p)
{
    // 雖然使用的是父類型的指針
    // 但虛函數最終會根據對象的真實類型調用。
    (*((Vtbl*)p->pvtbl)->pf1)();
}

void TestVtbl()
{
    // 子類的一個對象
    Derive s;
    Base *p = 0;

    // 初始化
    InitDerive(&s);
    p = (Base*)&s;

    // 調用Sfoo4
    ((SVtbl*)p->pvtbl)->pf4("Sfoo4");

    // 測試多態
    TestPolymorphism((Base*)&s);
}

int main() {     TestVtbl();     system("pause");     return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 結果: 

相關文章
相關標籤/搜索