由結構體對齊而引發的思考(二)類物件記憶體模型

2021-08-04 13:37:20 字數 2131 閱讀 6366

一 普通類的記憶體模型:

從一段簡單的**開始

[c++] 

純文字檢視 複製**

class

test 

};int

_tmain

(int

argc, _tchar

* argv)

inta;

intb;

intc;

double

d;char

e;};

class

inherit1 :public

base

intm_inherit1a;

};class

ctest

intm_inherit1a;

};int

main()

inta;

char

b;};

class

inherit1 :public

base

char

m_inherit1a;

};class

ctest

char

m_inherit1a;

};int

_tmain

(int

argc, _tchar

* argv)

inta;

char

b;};

class

inherit1 :public

base

char

m_inherit1a;

};class

ctest

char

m_inherit1a;

};int

_tmain

(int

argc, _tchar

* argv)

#include

using

namespace

std;

class

base

inta;int

b;int

c;int

d;char

e;};

class

inherit1 :public

base

char

c;double

m_inherit1a;

};class

ctest

char

c;double

m_inherit1a;

};int

main() {

base

obj1;

ctest

obj2;

inherit1

obj3;

cout

<<

"基類大小  :" <<

sizeof(obj1) <<

endl

;cout

<<

"測試類大小:"

<<

sizeof(obj2) <<

endl

;cout

<<

"子類大小  :" <<

sizeof(obj3) <<

endl

;return 0;

子類記憶體模型如下:

可以看出,父類與子類,依然涇渭分明,子類部分被擠榨的僅為12個位元組,整體上來說32位元組還是保證了為8的倍數。此時就出現了鬼神難料的一步,具有繼承關係的子類的大小竟然小於了父類與測試類大小的和。

總結一下:

1 當為普通繼承關係時,基類成員在派生類成員的上面

2 基類與子類的成員不會融合,也就是說,會保證基類大小是對齊過的。

3 無論是基類成員還是子類成員,排布其所在位置的偏移都是相對於整個類物件的起始位置。

4 靜態成員與成員函式對於類物件的記憶體排布沒有任何影響。

我們現在可以回答一開始提出的問題了

有可能sizeof(類a)+sizeof(類c)>sizeof(類b),也可能sizeof(類a)+sizeof(類c)

事情到這裡本就應該結束了,不過都看到這了,就再**一下子類與父類之間的關係。

(本文中某些問題還可以再做進一步**,這是原作者所沒有**的,如本文中前半部分子類都是以公共部分繼承的,如果以非公共部分繼承時將會發生怎樣的變化,這可以繼續**)

由結構體對齊而引發的思考。。。 一

由於本文初期在csdn中編輯的不是太好,現在將其發表於看雪論壇中,具體鏈結如下 從結構體對齊到 c 類物件記憶體模型之一結構體對齊 結構體與類在 c 中非常相似,他們的記憶體排布是乙個比較有意思的知識點,故而準備寫一些文章來 這些問題。首先從結構體的記憶體對齊說起,所有的測試環境都是 vs201x ...

由筆試題引發的結構體位元組對齊規則總結

今天做招銀網路的一道選擇題 給的正確答案是c,我選的a,之後又實測了下,認為就應該選a 很多網上的位元組對齊規則是這樣 按照這樣計算 struct mystruct innerstruct mystruct結構體的長度是 4 int 1 char 3 根據第一條,補齊innerstruct首位址為d...

由 引發的思考

前陣子在乙個移動專案中,通過 的方式 繫結click 事件來提交乙個表單,由於表單資訊比較敏感,於是採用的post 同步提交的方式,原本到也沒有什麼。後來萬惡的pm說 你這個按鈕呀,要固定在底部比較好 於是乎就通過 position fixed 固定到底部了。那麼,問題來了 在ios 下,虛擬鍵盤是...