亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

淺談C++中虛函數實現原理揭秘

2020-01-26 14:34:25
字體:
來源:轉載
供稿:網友

編譯器到底做了什么實現的虛函數的晚綁定呢?我們來探個究竟。     

編譯器對每個包含虛函數的類創建一個表(稱為V TA B L E)。在V TA B L E中,編譯器放置特定類的虛函數地址。在每個帶有虛函數的類 中,編譯器秘密地置一指針,稱為v p o i n t e r(縮寫為V P T R),指向這個對象的V TA B L E。通過基類指針做虛函數調 用時(也就是做多態調用時),編譯器靜態地插入取得這個V P T R,并在V TA B L E表中查找函數地址的代碼,這樣就能調用正確的函數使晚捆綁發生。為每個類設置V TA B L E、初始化V P T R、為虛函數調用插入代碼,所有這些都是自動發生的,所以我們不必擔心這些。利用虛函數, 這個對象的合適的函數就能被調用,哪怕在編譯器還不知道這個對象的特定類型的情況下。(《C++編程思想》)

在任何類中不存在顯示的類型信息,可對象中必須存放類信息,否則類型不可能在運行時建立。那這個類信息是什么呢?

我們來看下面幾個類:

class no_virtual

{public:  void fun1() const{}  int fun2() const { return a; }private:  int a;} class one_virtual{public:  virtual void fun1() const{}  int fun2() const { return a; }private:  int a;} class two_virtual{public:  virtual void fun1() const{}  virtual int fun2() const { return a; }private:  int a;} 

以上三個類中:

no_virtual沒有虛函數,sizeof(no_virtual)=4,

類no_virtual的長度就是其成員變量整型a的長度;

one_virtual有一個虛函數,sizeof(one_virtual)=8;

two_virtual 有兩個虛函數,sizeof(two_virtual)=8;

有一個虛函數和兩個虛函數的類的長度沒有區別,其實它們的長度就是no_virtual的 長度加一個void指針的長度,它反映出,如果有一個或多個虛函數,編譯器在這個結構中插入一個指針( V P T R)。在one_virtual 和 two_virtual之間沒有區別。這是因為V P T R指向一個存放地址的表,只需要一個指針,因為所有虛函數地址都包含在這個表中。 這個VPTR就可以看作類的類型信息。

那我們來看看編譯器是怎么建立VPTR指向的這個虛函數表的。先看下面兩個類:

class base{public:  void bfun(){}  virtual void vfun1(){}  virtual int vfun2(){}private:  int a;} class derived : public base{public:  void dfun(){}  virtual void vfun1(){}  virtual int vfun3(){}private:  int b;} 

兩個類VPTR指向的虛函數表(VTABLE)分別如下:

base類

 

      ――――――VPTR――> |&base::vfun1 |      ――――――     |&base::vfun2 |     ――――――

derived類

      ―――――――VPTR――> |&derived::vfun1 |      ―――――――     |&base::vfun2 |     ―――――――     |&derived::vfun3 |     ―――――――

每當創建一個包含有虛函數的類或從包含有虛函數的類派生一個類時,編譯器就為這個類創建一個VTABLE,如上圖所示。在這個表中,編譯器放置了在這個類 中或在它的基類中所有已聲明為virtual的函數的地址。如果在這個派生類中沒有對在基類中聲明為virtual的函數進行重新定義,編譯器就使用基類 的這個虛函數地址。(在derived的VTABLE中,vfun2的入口就是這種情況。)然后編譯器在這個類中放置VPTR。當使用簡單繼承時,對于每 個對象只有一個VPTR。VPTR必須被初始化為指向相應的VTABLE,這在構造函數中發生。

一旦VPTR被初始化為指向相應的VTABLE,對象就"知道"它自己是什么類型。但只有當虛函數被調用時這種自我認知才有用。       

個人總結如下:

1、從包含虛函數的類派生一個類時,編譯器就為該類創建一個VTABLE。其每一個表項是該類的虛函數地址。

2、在定義該派生類對象時,先調用其基類的構造函數,然后再初始化VPTR,最后再調用派生類的構造函數( 從二進制的視野來看,所謂基類子類是一個大結構體,其中this指針開頭的四個字節存放虛函數表頭指針。執行子類的構造函數的時候,首先調用基類構造函數,this指針作為參數,在基類構造函數中填入基類的vptr,然后回到子類的構造函數,填入子類的vptr,覆蓋基類填入的vptr。如此以來完成vptr的初始化。 )

3、在實現動態綁定時,不能直接采用類對象,而一定要采用指針或者引用。因為采用類對象傳值方式,有臨時基類對象的產生,而采用指針,則是通過指針來訪問外部的派生類對象的VPTR來達到訪問派生類虛函數的結果。       

VPTR 常常位于對象的開頭,編譯器能很容易地取到VPTR的值,從而確定VTABLE的位置。VPTR總指向VTABLE的開始地址,所有基類和它的子類的虛函 數地址(子類自己定義的虛函數除外)在VTABLE中存儲的位置總是相同的,如上面base類和derived類的VTABLE中vfun1和vfun2 的地址總是按相同的順序存儲。編譯器知道vfun1位于VPTR處,vfun2位于VPTR+1處,因此在用基類指針調用虛函數時,編譯器首先獲取指針指 向對象的類型信息(VPTR),然后就去調用虛函數。如一個base類指針pBase指向了一個derived對象,那pBase->vfun2 ()被編譯器翻譯為 VPTR+1 的調用,因為虛函數vfun2的地址在VTABLE中位于索引為1的位置上。同理,pBase->vfun3 ()被編譯器翻譯為 VPTR+2的調用。這就是所謂的晚綁定。

以上這篇淺談C++中虛函數實現原理揭秘就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲福利在线看| 欧美丝袜美女中出在线| 亚洲无线码在线一区观看| 2018国产精品视频| 精品国产一区二区三区久久狼黑人| 九九精品视频在线| 91精品国产一区| 久久男人av资源网站| 中文字幕亚洲情99在线| 亚洲国产一区二区三区四区| 国产日韩欧美日韩| 国产精品www网站| 成人黄色av免费在线观看| 国产日产欧美精品| 一本色道久久88精品综合| 狠狠躁夜夜躁人人爽天天天天97| 国产日韩在线亚洲字幕中文| 国产精品欧美激情在线播放| 欧亚精品中文字幕| 亚洲日本aⅴ片在线观看香蕉| 国产成人精品亚洲精品| 亚洲天堂一区二区三区| 国产午夜精品全部视频播放| 亚洲美女www午夜| 狠狠色狠色综合曰曰| 国产精品视频xxxx| 高清视频欧美一级| www.日韩视频| 欧美大片免费观看在线观看网站推荐| 97视频免费在线看| 欧美激情久久久久久| 国产精品免费久久久久久| 国产精品专区h在线观看| 精品一区二区三区四区在线| 欧美成人免费在线观看| 国内久久久精品| 久久影视三级福利片| 日韩精品在线视频观看| 51色欧美片视频在线观看| 日本一本a高清免费不卡| 亚洲第一网站男人都懂| 亚洲免费福利视频| 欧美性猛交xxxx乱大交极品| 国产成人免费av| 69av在线视频| 久久久免费精品| 亚洲自拍偷拍一区| 欧美性色视频在线| 欧美极品第一页| 91在线视频成人| 97超级碰在线看视频免费在线看| 国产va免费精品高清在线观看| 欧美一级成年大片在线观看| 欧美大荫蒂xxx| 欧洲成人午夜免费大片| 国产精品一区二区三区在线播放| 国产精品91久久久| 国产精品毛片a∨一区二区三区|国| 亚洲高清福利视频| 精品中文字幕在线2019| 91天堂在线观看| 成人欧美一区二区三区在线湿哒哒| 久久精品亚洲热| 最好看的2019的中文字幕视频| 欧美激情一区二区三区高清视频| 欧美在线视频a| 中文字幕亚洲自拍| 亚洲成人av片| 神马久久桃色视频| 亚洲国产另类久久精品| 国产在线精品成人一区二区三区| 欧美黑人狂野猛交老妇| 日韩在线观看免费| 国产精品视频永久免费播放| 欧美日韩美女视频| 欧美怡红院视频一区二区三区| 亚洲精品久久久久国产| 精品久久久中文| 日韩一二三在线视频播| 国产精品一区二区久久久久| 久久久久久欧美| 91精品国产99| 日韩成人久久久| 欧美大片va欧美在线播放| 国产精品视频精品视频| 国产精品人成电影| 精品久久久久久久久久久| 91在线免费观看网站| 91在线精品播放| 国产美女高潮久久白浆| 91九色在线视频| 久久久久日韩精品久久久男男| 国产免费一区视频观看免费| 亚洲欧美综合图区| 亚洲成人国产精品| 亚洲精品国精品久久99热| 亚洲性av在线| 国产亚洲精品美女久久久久| 国产精品美女久久久久av超清| 中文字幕亚洲欧美一区二区三区| 亚洲国产高清福利视频| 日韩在线观看免费全集电视剧网站| 自拍偷拍亚洲一区| 欧美电影在线观看完整版| 国产一区深夜福利| 日韩欧美视频一区二区三区| 欧美一级电影免费在线观看| 国产精品无av码在线观看| 日韩av免费一区| 国产精品久久9| 国产精品都在这里| 国产成人精品电影| 国产美女久久精品| 午夜精品久久久久久久白皮肤| 高清欧美性猛交xxxx黑人猛交| 久久久久久久网站| 亚洲国产精品久久久久秋霞蜜臀| 亚洲国产一区自拍| 亚洲一区中文字幕在线观看| 永久免费毛片在线播放不卡| 日韩av在线天堂网| 性欧美xxxx交| 亚洲老头老太hd| 日韩成人网免费视频| 日韩免费在线电影| 九九热精品视频国产| 日韩精品丝袜在线| 精品国产乱码久久久久久婷婷| 国产精品久久久亚洲| 欧美日韩免费在线| 久久亚洲精品国产亚洲老地址| 国产美女精彩久久| 欧美日韩成人精品| 97国产精品人人爽人人做| 91精品国产91久久久久福利| 亚洲电影成人av99爱色| 亚洲一区二区久久久| 亚洲精品视频中文字幕| 国产精品视频最多的网站| 欧美国产日韩免费| 秋霞午夜一区二区| 成人中文字幕在线观看| 欧美性xxxxx极品娇小| 国产一区二区欧美日韩| 国模视频一区二区| 久久在线免费视频| 这里只有精品在线观看| 91国语精品自产拍在线观看性色| 中日韩午夜理伦电影免费| 大荫蒂欧美视频另类xxxx| 亚洲一区二区免费| 操91在线视频| 国产69精品久久久久99| 这里只有精品在线播放| 少妇高潮久久77777| 日韩在线观看免费高清完整版| 日韩成人xxxx| 奇门遁甲1982国语版免费观看高清| 欧洲美女7788成人免费视频| 亚洲性av在线| 欧美精品日韩www.p站| 91视频国产一区| 国产精品在线看| 亚洲美腿欧美激情另类|