MSVC中C++的內(nèi)存模型

在MSVC環(huán)境下,虛繼承和虛函數(shù)是分開存放的,我們分開討論。

虛函數(shù)

1.當(dāng)一個類Base中有虛函數(shù)的時候,這個Base類中有一個虛函數(shù)表指針vfptr,指向一個虛函數(shù)表。虛函數(shù)表中有兩種東西:一個type_info(為了rtti)和虛函數(shù)指針。

2.若Base中有虛函數(shù),且Derived繼承了Base,那么Derived繼承Base中的vfptr,且有一個新的屬于Derived類的虛函數(shù)表,這個表里改寫type_info以及override的虛函數(shù)指針,在Base中沒被override的虛函數(shù)照抄。

3.若是多重繼承,即Derived繼承Base1,Base2,Base3。那么如果Base1、Base2、Base3中有vfptr,Derived都需要繼承。即,Derived中有三個vfptr,且有屬于Derived類的三個虛函數(shù)表。當(dāng)把derived對象賦值給Base2*的時候,在內(nèi)部需要有一個轉(zhuǎn)化,即Base2* base2 = (Base2*)((char*)derived + sizeof(Base1));,而且類的布局是固定的,所以不用擔(dān)心找不到或者找錯虛函數(shù)表。

虛繼承

1.若Derived虛繼承Base,那么Derived中有一個虛基類指針vbptr,指向一個虛基類表。虛基類表里存放的是虛基類Base的初始位置和子類Derived中vbptr的位置差。

2.若是多重虛繼承,即,Derived虛繼承Base1,Base2,Base3,那么Derived中仍然只有一個vbptr,但是其指向的虛基類表中有多個表項。

3.若是嵌套的虛繼承,即Derived虛繼承Base,DerivedDerived虛繼承Derived,那么一樣的,DerivedDerived中有一個vbptr,指向一個虛基類表。但是這個虛基類表有兩個表項,其中一個是Derived的初始位置和DerivedDerived中vbptr的位置差,另一個是Base在DerivedDerived中的初始位置和DerivedDerived中vbptr的位置差。多存一個嵌套的虛繼承基類的好處是,訪問的時間是固定的,而不會由嵌套的層次過深而增加指針的嵌套層次,從而增加訪問時間。

混合

若虛基類中沒有虛函數(shù),那么顯然,兩者還是沒有任何關(guān)系,各管各的。但是,若虛基類中有虛函數(shù),即,虛基類中有vfptr,那么會對整個內(nèi)存布局有重大的影響。假設(shè)若虛基類Base中有一個vfptr,其中有一個虛函數(shù)Base::f。

1.若Derived1虛繼承Base,且Derived1中沒有新的虛函數(shù)(即,Derived1中的虛函數(shù)要么是繼承自Base的,要么是override的),那么Derived1照如上所說,繼承Base中的vfptr。

2.若Derived2也虛繼承Base,且Derived1和Derived2都改寫了Base::f,那么DerivedDerived不能同時繼承Derived1和Derived2,因為這樣的話DerivedDerived中只有一個vfptr(虛基類在子類中只有一份)指向一個虛函數(shù)表,但是這個虛函數(shù)表中的f是矛盾的,既是Derived1::f,又是Derived2::f。所以,若Derived1和Derived2其中一個或零個改寫了Base::f,那么DerivedDerived是可以同時繼承Derived1和Derived2的,而且有趣的是,若Derived1改寫了Base::f,那么當(dāng)Derived2* derived2 = derivedDerived時,derived2->f()調(diào)用的是Derived1::f,盡管Derived1和Derived2沒什么關(guān)系。因為DerivedDerived的vfptr指向的虛函數(shù)表中的f就是Derived1::f。

3.若Derived虛繼承Base,且Derived中有新的虛函數(shù),那么Derived中有兩個vfptr,一個是從Base里面繼承來的,這個vfptr只管轄Base里面有的虛函數(shù),而新的vfptr則管轄新的虛函數(shù)。一方面,保留繼承來的vfptr,可以保證沒有新的虛函數(shù)時繼承的語義(即上面的1點和2點);另一方面,創(chuàng)建新的vfptr,可以保證在DerivedDerived多重繼承Derived1和Derived2的時候不會產(chǎn)生指向哪個表的沖突。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 經(jīng)常和年紀(jì)比自己小的群體接觸,會有一種小小的心酸,也談不上心酸,反正五味雜陳交錯著,這種感覺不是交流上的障礙,而是...
    阿熊what閱讀 225評論 0 0

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