週末看資料的時候,看到虛繼承和虛函式(兩者完全不是一碼事,正在寫乙個簡單的總結),進一步看到c++的類物件的記憶體模型,網上已有很多文章,自己也記錄一下。
研究問題從簡單入手,一步步深入。我們先來看乙個最簡單的模式;
class a;
用測試程式可以發現,a的物件的大小是4位元組,也就是a(int型別)的大小;
繼承:
classe:
public a
;
此時e的物件的大小就是8(2個成員a和e的大小),在記憶體中的分布也很明確,a(父類成員)在前,e(子類成員)在後;
下面來看虛繼承的場景,先上**:
classa;
classb:
virtual
public a
;classc:
virtual
public a
;classd:
public b,
public c
;
首先來看各個類的物件占用的記憶體大小:
a, b, c, d:
4, 16, 16, 40
這裡面涉及2個知識點,乙個是虛指標和虛表,乙個是記憶體對齊;
虛表 虛指標
a a;
b b;
printf
("&b = 0x%llx\n"
,&b)
;printf
("&b.a = 0x%llx\n"
,&b.a)
;printf
("&b.b = 0x%llx\n\n"
,&b.b)
;
結果如下:
&b =
0x7ffeec7657b8
&b.a =
0x7ffeec7657c4
&b.b =
0x7ffeec7657c0
我們可以做出如下猜測,對b的物件而言,其記憶體布局如下:
vbptr;
//虛指標,size=8(64位系統),0x7ffeec7657b8,也是該物件的起始位址
b;//繼承自父類的成員變數,size=4(int),0x7ffeec7657c0
a;//子類自己的成員變數,size=4(int),0x7ffeec7657c4
而對d而言,其列印結果為:
&d =
0x7ffeee9d9780
&d.a =
0x7ffeee9d97a0
&d.b =
0x7ffeee9d9788
&d.c =
0x7ffeee9d9798
&d.d =
0x7ffeee9d979c
可推測其記憶體布局為:
vbptr_b;
//虛指標,針對父類b的,size=8(64位系統),0x7ffeee9d9780,也是該物件的起始位址
b;//繼承自父類b的成員變數,size=4(int),0x7ffeee9d9788
vbptr_c;
//虛指標,針對父類c的,size=8(64位系統),0x7ffeee9d9790
c;//繼承自父類c的成員變數,size=4(int),0x7ffeee9d9798
d;//子類自己的成員變數,size=4(int),0x7ffeee9d979c
a;//祖父類a的成員變數,size=4(int),0x7ffeee9d97a0
通過上面的列印資訊可以看到,在類d的物件的成員位址的列印以及後續的記憶體模型推理上,我們發現:
b 和 vbptr_c 兩者的位址分別是:0x7ffeee9d9788 和 0x7ffeee9d9790;但b的size只有4,為啥卻缺了8呢?
這就是因為記憶體對齊,因為vbptr_b為8位元組,為了與vbptr_b保持對齊,故b也占用了8個位元組,而不是它自己的實際大小:4位元組
C 物件模型初探
在c 中有兩種class data members static和non static,以及三種class member functions static non static 和virtual。簡單物件模型 乙個object由一系列的slots組成,每乙個slot指向乙個member,slots按...
C 物件模型初探
測試環境 windows7 32 位機器上 vs2010 c 中的class從物件導向理論出發,將變數 屬性 和函式 方法 集中定義在一起,用於描述現實世界中的類。然而從計算機的角度,程式依然由資料段和 段構成。c 編譯器如何完成物件導向理論到電腦程式的轉化?換句話 c 編譯器是如何管理類 物件 類...
C 物件模型初探
最近看了侯捷的 深度探索c 物件模型 對c 的物件機制有了初步的了解。博主結合書上講的,和自己的理解簡單總結一下。class point對於類裡面的虛函式,c 物件模型以下面兩個方面加以支援 1.每乙個class產生一堆指向virtual functions的指標,放著virtual table中,...