[轉(zhuǎn)]深度探索C++對(duì)象模型(4)

類中函數(shù)的深度探索

類中包含的函數(shù)主要有三種:static成員函數(shù)隆夯、nostatic成員函數(shù)、virtual成員函數(shù)。

C++類中數(shù)據(jù)成員和成員函數(shù)的命名機(jī)制:

數(shù)據(jù)成員的命名:在每個(gè)數(shù)據(jù)成員命名的時(shí)候編譯器將該成員所屬的類名也添加上猜绣,用來標(biāo)志這個(gè)成員的來源范圍秩贰。這樣霹俺,繼承類就可以與子類用相同的名字命名其成員,這樣就不會(huì)產(chǎn)生二義性和沖突毒费,但是對(duì)外界而言丙唧,通過繼承類對(duì)象訪問該名字,只會(huì)獲取繼承類的數(shù)據(jù)成員觅玻,因?yàn)楦鶕?jù)命名查找機(jī)制想际,兩個(gè)名字屬于不同的作用域,繼承類中的成員覆蓋了子類中的成員串塑,想要調(diào)用必須顯示調(diào)用子類成員或在繼承類作用域中使用using沼琉。(函數(shù)名相同)

成員函數(shù)的命名:在同一個(gè)類中允許函數(shù)重載,重載的機(jī)制就是對(duì)函數(shù)名+參數(shù)名編碼獲得唯一的編碼識(shí)別桩匪。

(1)static成員函數(shù)

首先打瘪,說明static成員函數(shù)的幾條限制:1)static成員函數(shù)只能使用static數(shù)據(jù)成員;2)static成員函數(shù)不能設(shè)為const傻昙、virtual闺骚、inline函數(shù),只能保持一份實(shí)例妆档;3)static成員函數(shù)不使用this指針僻爽,因此不必需要通過對(duì)象來訪問,雖然很多時(shí)候是這樣使用的贾惦。

static成員函數(shù)在內(nèi)存空間中只有一份實(shí)例胸梆,如果取函數(shù)的地址,得到的是真實(shí)的內(nèi)存地址须板,其函數(shù)指針是與普通函數(shù)相同的函數(shù)指針碰镜,而不是指向成員函數(shù)的指針,例如

static int foo(); int (*p)()=&A::foo; 使用方法與普通函數(shù)指針相同习瑰。

因此绪颖,對(duì)于static成員函數(shù)的調(diào)用與調(diào)用非成員函數(shù)的效率是相同的。

(2)nostatic成員函數(shù)

雖然nostatic成員函數(shù)也是存放在對(duì)象外的內(nèi)存空間中甜奄,且取其函數(shù)地址也是真實(shí)的內(nèi)存地址柠横,但是調(diào)用nostatic成員函數(shù)也需要通過對(duì)象,也就是說需要this指針课兄,因?yàn)閚ostatic成員函數(shù)中可以直接使用類數(shù)據(jù)成員牍氛。

編譯器將this指針作為參數(shù)傳進(jìn)nostatic成員函數(shù)中去,然后通過this指針訪問數(shù)據(jù)成員烟阐。例如:

int foo();A a;a.foo();編譯器將轉(zhuǎn)化為foo(&a);

編譯器將成員函數(shù)轉(zhuǎn)化為了非成員函數(shù)糜俗,是的對(duì)成員函數(shù)的調(diào)用不會(huì)有異于非成員函數(shù)。

成員函數(shù)的指針的使用也必須通過對(duì)象調(diào)用,例如

int (A::p)()=&A::foo;(a.p)();相當(dāng)于p(&a)調(diào)用悠抹,也可以由其繼承類對(duì)象調(diào)用。

(3)virtual函數(shù)

虛擬成員函數(shù)地址存放在虛表中扩淀,而獲得到虛表的訪問權(quán)仍然需要通過對(duì)象的地址楔敌。

指向虛擬成員函數(shù)的指針獲取到的虛擬成員函數(shù)的地址實(shí)際上是虛擬函數(shù)在虛表中slot編號(hào),通過該編號(hào)可以獲取到虛擬成員函數(shù)的地址驻谆,也正是因?yàn)楂@取得到的是編號(hào)而非真正的內(nèi)存地址卵凑,才能實(shí)現(xiàn)多態(tài)機(jī)制。

1)單一繼承

單一繼承情況下胜臊,子類會(huì)繼承父類的vptr指針和虛表勺卢,不會(huì)產(chǎn)生新的vptr,這時(shí)象对,子類中若存在不同與父類的虛擬函數(shù)黑忱,將會(huì)添加到虛表的尾部,子類若修改了父類中虛擬函數(shù)的定義勒魔,將會(huì)在虛表中相應(yīng)的位置進(jìn)行覆蓋指向新的函數(shù)地址甫煞,也就是說,子類的虛表是在父類虛表的基礎(chǔ)上擴(kuò)展修改得到的冠绢。

Paste_Image.png

2)多重繼承

多重繼承中牽扯到this指針調(diào)整的問題抚吠,也就是第二個(gè)及以后的父類地址的問題。C++中將繼承類的虛函數(shù)寫到第一個(gè)父類的虛表中弟胀,而第一個(gè)父類的虛表也就成為主虛表楷力,其他的則成為次虛表。

在繼承類中修改的虛函數(shù)將會(huì)覆蓋所有的虛表中原虛函數(shù)孵户,<strong>凡是繼承類中存在的虛函數(shù)都會(huì)在主虛表中出現(xiàn)萧朝,</strong>對(duì)于沒有修改的虛函數(shù),其實(shí)際地址存放位置仍然在原父類的虛表中延届,調(diào)用的時(shí)候需要進(jìn)行this指針調(diào)整剪勿。

Paste_Image.png

如圖,Derived a;a.mumble();的調(diào)用將會(huì)在主虛表中查到4號(hào)函數(shù)方庭,然后將this指針調(diào)整到Base2位置厕吉,同多Base2 子對(duì)象調(diào)用mumble()函數(shù)。

再例如械念,Base2 *p=new Derived; delete p;也會(huì)產(chǎn)生this指針的調(diào)整头朱,必須調(diào)用正確的析構(gòu)函數(shù),this指針必須回到真?zhèn)€Derived對(duì)象的地址首部龄减。

因此项钮,對(duì)于多重繼承主要是要考慮this指針的調(diào)整問題。

3)虛擬繼承

虛擬繼承的子類將會(huì)產(chǎn)生一個(gè)vptr和一個(gè)虛表來存儲(chǔ)子類中虛擬函數(shù)和其子類對(duì)象的地址。

虛擬繼承也需要進(jìn)行this指針的調(diào)整烁巫,如同多重繼承一樣署隘,但是this指針的調(diào)整更加復(fù)雜,建議不要在虛擬基類中定義nostatic成員亚隙,這樣會(huì)使虛擬子類對(duì)象的offset值的確定變得過于復(fù)雜磁餐。(在不同子類中,虛擬子對(duì)象的offset是不相同的)阿弃。

原文地址:http://www.cnblogs.com/tracylee/archive/2012/12/20/2825562.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诊霹,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子渣淳,更是在濱河造成了極大的恐慌脾还,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件入愧,死亡現(xiàn)場(chǎng)離奇詭異鄙漏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)砂客,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門泥张,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鞠值,你說我怎么就攤上這事媚创。” “怎么了彤恶?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵钞钙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我声离,道長(zhǎng)芒炼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任术徊,我火速辦了婚禮本刽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赠涮。我一直安慰自己子寓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布笋除。 她就那樣靜靜地躺著斜友,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垃它。 梳的紋絲不亂的頭發(fā)上鲜屏,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天烹看,我揣著相機(jī)與錄音,去河邊找鬼洛史。 笑死惯殊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的也殖。 我是一名探鬼主播靠胜,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼毕源!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起陕习,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤霎褐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后该镣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冻璃,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年损合,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了省艳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嫁审,死狀恐怖跋炕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情律适,我是刑警寧澤辐烂,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站捂贿,受9級(jí)特大地震影響纠修,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厂僧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一扣草、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧颜屠,春花似錦辰妙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蕴坪,卻和暖如春肴掷,著一層夾襖步出監(jiān)牢的瞬間敬锐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工呆瞻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留台夺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓痴脾,卻偏偏與公主長(zhǎng)得像颤介,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赞赖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容