對齊理由:
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...