這裡的例子全部來自陳皓的 c++ 物件的記憶體布局(上)
,經過修改的。而c++ 物件的記憶體布局(下)看了沒有什麼問題的樣子,沒有時間測試了。
編譯器:g++ (ubuntu 4.9.2-10ubuntu13) 4.9.2
單一的一般繼承,所有函式均是virtual,每個類中均有1個long long變數:
1示例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 }
、解釋:繼承關係為 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示例2輸出: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 }
總結:物件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成員變數會造成不同的記憶體...