C++多態(tài)——虛函數(shù)表vtable

純Swift類的函數(shù)調(diào)用原理,類似于C++的虛函數(shù)表

  • 純Swift類的函數(shù)調(diào)用,類似于C++的虛函數(shù)表,是編譯時(shí)決議的。所以專門了解一下vtable還是有必要的。
  1. 一個(gè)含有虛函數(shù)的類,在創(chuàng)建對(duì)象時(shí)會(huì)額外增加一張?zhí)摫韛table,表中每一項(xiàng)記錄了虛函數(shù)的入口地址,編譯時(shí)對(duì)象會(huì)增加一個(gè)虛指針vpt(四個(gè)字節(jié)),指向虛函數(shù)表的起始位置,將對(duì)象和表關(guān)聯(lián)起來(lái)。

2.下面舉個(gè)栗子,含有虛函數(shù)的單繼承多層次的類關(guān)系:

using namespace std;

class A {
protected:
    int a1;
    int a2;
    
public:
    virtual void display() { std::cout<<"A:dis() \n"; }
    virtual void clone() { std::cout<<"A:clone()"; }
};

class B: public A {
protected:
    int b;
    
public:
    virtual void display() { std::cout<<"B:dis() \n"; }
    virtual void init() { cout<<"B:init()"; }
};

class C: public B {
protected:
    int c;
    
public:
    virtual void display() { std::cout<<"C:dis() \n";
                             A::display(); }
    virtual void execute() { cout<<"C:execute"<<this->a1<<"\n"; }
};

int main(int argc, const char * argv[]) {

    C *p = new C();
    p->display();
    p->execute();
    
    return 0;
}
類和虛表關(guān)系圖.png
  • 從上圖可以知道,對(duì)于單繼承,無(wú)論繼承層次多深,都只是增加一個(gè)指針;基類中的虛函數(shù)在vtable中的索引是固定的,不會(huì)隨著繼承層次的增加而改變。例如,display()的索引值始終是0.
  • 當(dāng)調(diào)用函數(shù)時(shí),利用指針vfptr間接轉(zhuǎn)換,可得到虛函數(shù)的入口地址:
    比如,調(diào)用p->display()
    在編譯器內(nèi)進(jìn)行轉(zhuǎn)換,變成:((p->vptr)[0])(p);
    其中,0是display()在vtable的索引值,
    (p->vptr)[0]是它的入口地址。
    所以調(diào)用對(duì)象的不同虛函數(shù),其實(shí)是訪問(wèn)虛函數(shù)表,通過(guò)改變不同的索引值,從而訪問(wèn)到函數(shù)的入口地址。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容