C 物件記憶體模型初探

2021-10-25 10:15:28 字數 2065 閱讀 1599

週末看資料的時候,看到虛繼承和虛函式(兩者完全不是一碼事,正在寫乙個簡單的總結),進一步看到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中,...