虛函數(shù)實(shí)現(xiàn)的基本原理(轉(zhuǎn)載)

技術(shù)交流QQ群:1027579432,歡迎你的加入!

1.概述

  • 每一個(gè)含有虛函數(shù)(無論是其本身就含有的,還是從基類繼承過來的)的類都至少有一個(gè)與之對(duì)應(yīng)的虛函數(shù)表趣斤,其中存放著該類所有的虛函數(shù)對(duì)應(yīng)的函數(shù)指針俩块。如下圖所示

    虛函數(shù)表.png

    其中:
    • B的虛函數(shù)表中存放著B::foo和B::bar兩個(gè)函數(shù)指針
    • D的虛函數(shù)表中存放的既有繼承自B的虛函數(shù)B::foo黎休,又有重寫了基類虛函數(shù)B::bar的D::bar,還有新增的虛函數(shù)D::quz玉凯。

2.虛函數(shù)表的構(gòu)造過程

  • 從編譯器的角度來說势腮,B的虛函數(shù)表很好構(gòu)造,D的虛函數(shù)表構(gòu)造過程相對(duì)復(fù)雜漫仆,下面給出了構(gòu)造D的虛函數(shù)表的一種方式捎拯,該過程是由編譯器完成的,即虛函數(shù)替換過程發(fā)生在編譯時(shí):


    D的虛函數(shù)表構(gòu)造過程.png

3.虛函數(shù)的調(diào)用過程

  • 以下面的程序?yàn)槔?/p>

    虛函數(shù)的調(diào)用過程.png
  • 編譯器只知道pb是B*類型的指針盲厌,并不知道它指向的具體對(duì)象類型署照,pb可能指向的是B的對(duì)象,也有可能指向的是D的對(duì)象吗浩。但對(duì)于pb->bar()建芙,編譯時(shí)能確定的是:此處->的另一個(gè)參數(shù)是B::bar(因?yàn)閜b是B*類型的,編譯器認(rèn)為bar是B::bar)懂扼,而B::bar和D::bar在各自虛函數(shù)表中的偏移位置是相等的禁荸。無論pb指向哪種類型的對(duì)象右蒲,只要能夠確定被調(diào)函數(shù)在虛函數(shù)表的偏移值,等到運(yùn)行時(shí)能夠確定具體類型赶熟,并能找到相應(yīng)的vptr瑰妄,這樣就能找出真正應(yīng)該調(diào)用的函數(shù)。由于虛函數(shù)指針中的ptr部分為虛函數(shù)表中的偏移值(以字節(jié)為單位)+1映砖,所以B::bar是一個(gè)虛函數(shù)指針间坐,它的ptr部分內(nèi)容是9,它在B的虛函數(shù)表中的偏移值為8邑退。當(dāng)程序執(zhí)行到pb->bar()時(shí)眶诈,已經(jīng)能夠判斷pb指向的具體類型了:
    • a.如果pb指向B的對(duì)象,可以獲取到B對(duì)象的vptr瓜饥,加上偏移值8(char(*)vptr + 8)逝撬,可以找到B::bar
    • b.如果pb指向的是D的對(duì)象,可以獲取D的對(duì)象vptr乓土,加上偏移值8(char(*)vptr + 8)宪潮,可以找到D::bar

3.多重繼承

  • 當(dāng)一個(gè)類繼承多個(gè)類,且多個(gè)基類都有虛函數(shù)時(shí)趣苏,子類對(duì)象中將包含多個(gè)虛函數(shù)表中的指針(即多個(gè)vptr)狡相,如下所示:


    多重繼承.png
  • 其中:D的自身虛函數(shù)與B基類共用了同一個(gè)虛函數(shù)表,因此稱B為D的主基類食磕。虛函數(shù)替換過程與前面描述類似尽棕,只是多了一個(gè)虛函數(shù)表,多了一次拷貝和替換的過程彬伦。虛函數(shù)的調(diào)用過程滔悉,與前面基本類似,區(qū)別在于基類指針指向的位置可能不是派生類對(duì)象的起始位置单绑,如下面的程序所示:


    多重繼承的函數(shù)調(diào)用.png

4.博客原文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末回官,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子搂橙,更是在濱河造成了極大的恐慌歉提,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件区转,死亡現(xiàn)場離奇詭異苔巨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)废离,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門侄泽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人厅缺,你說我怎么就攤上這事蔬顾⊙绯ィ” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵诀豁,是天一觀的道長窄刘。 經(jīng)常有香客問我,道長舷胜,這世上最難降的妖魔是什么娩践? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮烹骨,結(jié)果婚禮上翻伺,老公的妹妹穿的比我還像新娘。我一直安慰自己沮焕,他們只是感情好吨岭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著峦树,像睡著了一般辣辫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上魁巩,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天急灭,我揣著相機(jī)與錄音,去河邊找鬼谷遂。 笑死葬馋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肾扰。 我是一名探鬼主播畴嘶,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼白对!你這毒婦竟也來了掠廓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤甩恼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后沉颂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體条摸,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年铸屉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钉蒲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彻坛,死狀恐怖顷啼,靈堂內(nèi)的尸體忽然破棺而出踏枣,到底是詐尸還是另有隱情,我是刑警寧澤钙蒙,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布茵瀑,位于F島的核電站,受9級(jí)特大地震影響躬厌,放射性物質(zhì)發(fā)生泄漏马昨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一扛施、第九天 我趴在偏房一處隱蔽的房頂上張望鸿捧。 院中可真熱鬧,春花似錦疙渣、人聲如沸匙奴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饥脑。三九已至,卻和暖如春懦冰,著一層夾襖步出監(jiān)牢的瞬間灶轰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工刷钢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笋颤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓内地,卻偏偏與公主長得像伴澄,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子阱缓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355