C++對象模型

C++對象模式

C++中的成員:

  • 成員變量:靜態(tài)變量非靜態(tài)變量
  • 成員函數(shù):靜態(tài)函數(shù)绍坝、非靜態(tài)函數(shù)徘意、虛函數(shù)

1. 簡單對象模型

  • 對象中只存放指向成員的指針,這么做可以避免成員不同類型轩褐,不同存儲空間的尷尬
  • 對象所占內(nèi)存大小為指針大小 * 成員數(shù)量(成員函數(shù) + 成員變量)

2. 表格驅(qū)動對象模型

  • 對象本身只有兩個指向表格的指針椎咧,成員變量表成員函數(shù)表
  • 成員變量表直接存儲變量本身
  • 成員函數(shù)表存儲函數(shù)指針
  • 這種理念是虛函數(shù)表得雛形

3. C++對象模型

  • C++對象模型是從簡單對象模型派生而來的,并對內(nèi)存空間和存取時間做了優(yōu)化
  • 對象本身只有變量一個虛指針
  • 虛指針(vptr)指向虛函數(shù)表(vtbl)
  • 變量:只有非靜態(tài)成員變量存儲在對象內(nèi)存中把介,其他靜態(tài)成員變量所有成員函數(shù)(包括靜態(tài)和非靜態(tài)的)都在對象內(nèi)存之外
  • 注意:C++對象的第一個字節(jié)為虛指針勤讽;虛函數(shù)表中的前面的指針為虛函數(shù)指針,最后才是指向type_info對象的指針

C++類成員函數(shù)

"類根本就沒有成員函數(shù)"

  • 因?yàn)閺膬?nèi)存布局上看拗踢,內(nèi)存布局中只有成員變量的空間脚牍,并沒有成員函數(shù)的內(nèi)存空間
  • 當(dāng)我們在一個類中聲明一個成員函數(shù)時,編譯器隱藏了第一個參數(shù)巢墅,實(shí)際上成員函數(shù)儲存在代碼區(qū)莫矗,長這個樣子:
    void memberFunc(Object* this, int arg1, int arg2)
    并且這個函數(shù)參數(shù)this只有接收所屬類類型指針時才能調(diào)用
  • 所謂的 .運(yùn)算符或者->運(yùn)算符,實(shí)際是把this指針傳遞給函數(shù)砂缩,調(diào)用時長這個樣子:
    void memberFunc(this, this->arg1, this->arg2)

C++對象模型優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):相對于簡單模型的通過指針間接訪問數(shù)據(jù)的思想,C++模型提高了訪問數(shù)據(jù)的效率三娩,并參考表格驅(qū)動理念設(shè)計了虛函數(shù)表庵芭,節(jié)約了對象空間。
  • 缺點(diǎn):修改對象的非靜態(tài)成員變量(增刪改)雀监,用到此對象的代碼就需要重新編譯双吆。

深入理解虛函數(shù)、虛函數(shù)表

作用:

  • 為了實(shí)現(xiàn)多態(tài)的機(jī)制会前,簡而言之就是用父類指針指向其子類的實(shí)例好乐,然后通過父類的指針調(diào)用實(shí)例子類的成員函數(shù)。這種技術(shù)可以讓父類的指針有"多種形態(tài)"——多態(tài)

虛函數(shù)表

  • 即類的虛函數(shù)的地址表瓦宜,表的本質(zhì):指針數(shù)組
  • 表的最后一個位是null指針
  • 只有有虛函數(shù)的類蔚万,他的內(nèi)存中才會有虛指針,且該指針存在于實(shí)例中最前面的位置(保證取到虛函數(shù)表的有最高的性能)


    image.png

一般繼承(無虛函數(shù)重寫時)

image.png

image.png
  • 虛函數(shù)按照其聲明順序放于表中
  • 父類的虛函數(shù)在子類的虛函數(shù)前面

一般繼承(有虛函數(shù)重寫時)

image.png

image.png
  • 覆蓋的函數(shù)被放到了虛表中原來父類虛函數(shù)的位置临庇,由于函數(shù)指針被子類函數(shù)取代反璃,所以實(shí)際調(diào)用時昵慌,調(diào)用的是子類的同名函數(shù),因此實(shí)現(xiàn)多態(tài)
  • 沒有被覆蓋的函數(shù)依舊

多重繼承(無虛函數(shù)重寫時)

image.png

image.png
  • 子類實(shí)例中淮蜈,針對每個父類都有自己的虛表斋攀,因此每多繼承一個父類,子類實(shí)例中僅僅只是增加一個虛指針的空間而已
  • 子類自己的虛函數(shù)被放到了第一個父類的表中梧田,按照聲明順序確定誰是第一父類
    這樣做就是為了解決不同的父類類型的指針指向同一個子類實(shí)例淳蔼,而能夠調(diào)用到實(shí)際的函數(shù)。

多重繼承(有虛函數(shù)重寫時)

image.png

image.png
  • 三個父類虛函數(shù)表中的f()的位置被替換成了子類的函數(shù)指針裁眯。這樣鹉梨,我們就可以任一靜態(tài)類型的父類來指向子類,并調(diào)用子類的f()了

虛函數(shù)表的缺點(diǎn)

  • 不安全性:來源于虛函數(shù)表的本質(zhì)還是一個指針數(shù)組


    image.png
  • 例如上圖未状,根據(jù)C++語義俯画,在沒有重寫父類的虛函數(shù)時,我們是無法通過父類指針來調(diào)用子類自己的虛函數(shù)
Base * base = new Derive;
base->g1(); // 編譯錯誤
  • 但是根據(jù)繼承模型司草,子類對象還是會將父類與自己的所有虛函數(shù)放在一個虛表中,因此就導(dǎo)致可以通過指針的方式訪問虛函數(shù)表中的任意函數(shù)
  • 同樣的道理艰垂,即使是non-public的繼承方式,這些非public的虛函數(shù)同樣會存在于虛函數(shù)表中
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末埋虹,一起剝皮案震驚了整個濱河市猜憎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌搔课,老刑警劉巖胰柑,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異爬泥,居然都是意外死亡柬讨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門袍啡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踩官,“玉大人,你說我怎么就攤上這事境输≌崮担” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵嗅剖,是天一觀的道長辩越。 經(jīng)常有香客問我,道長信粮,這世上最難降的妖魔是什么黔攒? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上亏钩,老公的妹妹穿的比我還像新娘莲绰。我一直安慰自己,他們只是感情好姑丑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布蛤签。 她就那樣靜靜地躺著,像睡著了一般栅哀。 火紅的嫁衣襯著肌膚如雪震肮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天留拾,我揣著相機(jī)與錄音戳晌,去河邊找鬼。 笑死痴柔,一個胖子當(dāng)著我的面吹牛沦偎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咳蔚,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼豪嚎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谈火?” 一聲冷哼從身側(cè)響起侈询,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糯耍,沒想到半個月后扔字,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡温技,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年革为,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舵鳞。...
    茶點(diǎn)故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡篷角,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出系任,到底是詐尸還是另有隱情,我是刑警寧澤虐块,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布俩滥,位于F島的核電站,受9級特大地震影響贺奠,放射性物質(zhì)發(fā)生泄漏霜旧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挂据。 院中可真熱鬧以清,春花似錦、人聲如沸崎逃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽个绍。三九已至勒葱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巴柿,已是汗流浹背凛虽。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留广恢,地道東北人凯旋。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像钉迷,于是被迫代替她去往敵國和親至非。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評論 2 349