C 中類的資料成員和成員函式記憶體分布

2021-10-25 05:50:31 字數 2192 閱讀 3541

對齊理由:

1、移植原因。某些平台只能在特定位址處取特定資料值。

2、效能原因。訪問未對齊的記憶體,處理器需要額外的訪問次數。有的平台從偶位址開始讀,如果資料從奇位址開始讀,那麼需要訪問兩次。跟物理性質有關,記憶體分一塊一塊等大小的,盡量將單個資料儲存在乙個物理儲存上,便於電訊號讀取。

1、空型別

class

base1

;void

main()

編譯器會安插乙個char到空類中。這樣這個類定義出來的兩個物件在記憶體中就是獨一無二的。

2、非空型別

#pargma pck (n) ,n為對齊模數。

//pargma pck (4) 

class

myclass

;void

main()

class

base1

;class

base2

:public base1

;class

base3

:public base2

;void

main()

base1後面3個位元組個填補位元組, 佔8個位元組; base2繼承base1,多了4個位元組,並沒有直接將m_char2填補base1的空白位。

如果為減少記憶體浪費,將m_char2緊放入base1後的3個填補位元組,當將base1物件賦值給base2,會導致m_char2被修改。

class

point2d

;float _x,_y;};

class

point3d

:public point2d

;class

vertex

;class

point4d

:public point2d,

public vertex

;void

main()

;};class

base2

:virtual

public base1

;char m_char2;};

class

base3

:virtual

public base1

;char m_char3;};

class

base4

:public base2,

public base3

;//如果base4不包含func1,則會出現二義性,不知繼承的是base2還是base3的};

void

main()

vs2020

虛函式表,虛基表

base1 : m_val, m_char1, _vptr_base1

base2 : m_char2, vbptr_base2,m_val, m_char1, _vptr_base1,

base3 : m_char3, vbptr_base3, m_val, m_char1, _vptr_base1,

base3 : m_char2, vptr_base2, m_char3, vptr_base3, m_val, m_char1, _vptr_base1,

由於base2,base3是虛繼承base1,所以編譯器為了解決菱形繼承所帶來的「二義性」以及「資料冗餘」,便將a放在最末端,並在子類中存放乙個虛基表,方便找到父類;

而虛基表的前四個位元組存放的是對於自己虛函式表的偏移量,再往下四個位元組才是對於父類的偏移量。

一般的編譯器是,如果class內含乙個或多個virtual base class,則物件會被分隔成兩部分:乙個不變區域和乙個共享區域。

對於不變區域中的資料,不管後續如何衍化,總是擁有固定的offset,所以這一部分資料可以被直接訪問。對於共享區域,就是virtual base class物件資料,其位置會因為每次的派生操作而有變化,所以他們只能被間接訪問。

一般的編譯器會在虛函式表中放置虛基類的偏移,和虛函式指標放在混在一起。可通過虛函式表的索引值進行區分。正值,是虛函式,負值,則是虛基類。

這樣虛繼承的記憶體分布就和普通繼承一樣了,但是對於虛基類中的成員做訪問操作,需要先去虛函式表中進行索引,然後進行訪問操作,時間會稍微慢些。

參考:關於c++物件繼承中的記憶體布局示例詳解

c++ 類中資料成員分布詳解

c 類中資料成員和成員函式的儲存方式

我們都知道在例項化類得到物件時,系統會為類內的資料成員和成員函式分配儲存空間 但是如果我們用同乙個類例項化多個物件呢?那麼是不是系統要為每乙個物件中的成員函式分配儲存空間?實際上不是這樣的!當例項化類得到物件時系統只為物件的資料成員分配記憶體空間,而將類的成員函式放在另乙個公共的區域。所以,無論例項...

《物件導向程式設計 C 》類資料成員和類成員函式

c 類中有一種型別成員,屬於類本身,而不屬於類的物件,這種型別成員成為類成員,而屬於物件的成員成為物件成員或例項成員。可以使用關鍵字static來建立乙個類成員。class c unsigned c n 0 在外部定義時不需要加static在類宣告內部宣告的static資料成員必須在任何程式塊之外定...

成員變數和成員函式記憶體分配

在c 中,成員變數和成員函式分開儲存,只有非靜態成員變數才屬於類的物件上。非靜態成員函式,靜態成員函式,靜態成員變數占用的記憶體均不占用類的物件空間上。示例1 include include using namespace std class person 非靜態成員函式 不屬於類的物件上 stat...