C 物件的記憶體布局

2022-05-16 02:29:53 字數 3385 閱讀 2647

這裡的例子全部來自陳皓的  c++ 物件的記憶體布局(上)

,經過修改的。而c++ 物件的記憶體布局(下)看了沒有什麼問題的樣子,沒有時間測試了。

編譯器:g++ (ubuntu 4.9.2-10ubuntu13) 4.9.2

單一的一般繼承,所有函式均是virtual,每個類中均有1個long long變數:

1

class

parent

5virtual

void f()

6virtual

void g()

7virtual

void h() 89

};10

11class child : public

parent

15virtual

void f()

16virtual

void g_child()

17virtual

void h_child()

18};

1920

class grandchild : public

child

24virtual

void f()

25virtual

void g_child()

26virtual

void h_grandchild()

27};

28int main(void)29

42 ll *p=(ll*)&gc;

43 cout << "

[1] parent.iparent =

"<

44 cout << "

[2] child.ichild =

"<< *(p+2)<

45 cout << "

[3] grandchild.igrandchild =

"<< *(p+3)<

4647 cout<

物件gc的大小:

"<

4849

return0;

50 }

示例1輸出:

、解釋:繼承關係為 parent

總結:grandchild的物件gc一共佔4*8=32個位元組。其中首項是虛函式表指標,剩下的3項是3個類中的成員變數,按繼承的宣告順序排列。虛函式表中有6個函式,其中來自grandchild的有3個,child的1個,parent的2個。grandchild的3個必定不會少,而且前兩個函式f和g_child就覆蓋掉所有基類中同名的函式。parent中剩下2個沒有被覆蓋的,而f不幸被覆蓋。child中只剩下1個了,前兩個都被覆蓋了。

其實可以先看兩層的parent

驗證了如下這副圖:

多重繼承,基類與派生類中有同名虛函式,每個類中有自己的1個變數。

1

class

base1

5virtual

void f()

6virtual

void g()

7virtual

void h() 89

};10

11class

base2

15virtual

void f()

16virtual

void g()

17virtual

void h()

18};

1920

class

base3

24virtual

void f()

25virtual

void g()

26virtual

void h()

27};

2829

class derive : public base1, public base2, public

base3

33virtual

void f()

34virtual

void g1()

35};

3637

int main(void)38

51 pfun = (fun)pvtab[0][4

];52 cout << "

[4]

"53 cout << "

[1] base1.ibase1 =

"<< (ll)pvtab[1] <

5455

56 cout << "

[4] base3::_vptr->

"<

57for(int i=0; i<3; i++)

5863 pfun = (fun)pvtab[4][4

];64 cout << "

[4]

"65 cout << "

[5] base3.ibase3 =

"<< (ll)pvtab[5] <

6667

return0;

68 }

示例2輸出:

總結:物件d中分4個部分。

第一部分是基類base1的,共2*8=16個位元組,前8個位元組是虛函式表的指標,後8個位元組是變數ibase1的值。

第二部分是基類base2的,共2*8=16個位元組,前8個位元組是虛函式表的指標,後8個位元組是變數ibase2的值。

第三部分是基類base3的,共2*8=16個位元組,前8個位元組是虛函式表的指標,後8個位元組是變數ibase3的值。

第四部分是派生類derive的,共1*8=8個位元組,這8個位元組儲存著變數iderive的值。

物件d合計3*16+8=56個位元組。

同預計一樣,派生類derive中的虛函式依然儲存在和基類base1在一起,緊跟在其後面。而派生類derive中的虛函式f 分別覆蓋掉3個基類中的虛函式f ,並且存在於他們各自的虛函式表中。

驗證了如下這副圖(null就是那個標誌1):   

C 物件的記憶體布局

一篇寫的比較好的部落格 這篇文章中主要想說以下幾個問題 1 如何通過物件獲得虛函式表中虛函式的位址 2 分幾種情況討論記憶體布局 1 單一繼承 2 多重繼承 3 重複繼承 4 鑽石虛擬繼承 為了解決重複繼承中出現問題而產生的虛擬繼承 1 虛函式主要是通過一張虛函式的位址表來實現的,簡稱v table...

C 物件的記憶體布局

記憶體布局是屬於較深層次的知識,很多問題往深了講都是不清楚記憶體布局的原理。最近讀到一本書,裡面講了一部分c 物件的記憶體布局,讓我對很多以前的問題都豁然開朗了。書上篇幅較大,我加上自己的理解總結了下。分為三部分 簡單物件,單繼承,多繼承 非靜態成員變數和虛函式是決定類大小的唯一兩個因素 非靜態成員...

C 物件的記憶體布局

主要有三個因素對物件的記憶體布局有較大影響 類成員型別 static成員變數,virtual成員函式 繼承方式 記憶體對齊。以下分別詳細說明了具體的影響。一 static與virtual對記憶體布局的影響 物件的記憶體分布與類的成員有關,static成員變數與非static成員變數會造成不同的記憶體...