a:有關因素:普通成員變數;虛函式;繼承(單一繼承,多重繼承,重複繼承,虛擬繼承)b:無關因素:靜態成員變數;靜態成員函式;普通成員函式
a:對於成員函式來說,函式名本身就指明了函式是屬於哪個類的(連引數型別都有),因此,編譯器在編譯**時,可以直接呼叫該類的成員函式,而不需要類本身提供任何資訊。b: 對於靜態成員變數來說, 靜態成員變數占用全域性的記憶體. 和全域性變數分配的內存在同乙個區域裡面.,而sizeof()計算的是棧區的大小。
class
student
;
對於空類來說,即使它裡面沒有任何成員,它的大小也不會為0。因為空類也是可以例項化的,例如:對於上面的空類,一以下例項化時沒有問題的 *student std; 那麼既然可以例項化,例項化之後必然在記憶體中佔據位置,所以編譯器將其大小優化為 1 位元組
class
student1
;class
student2
;
根據記憶體對齊規則:sizeof(student1) = 16;sizeof(student2) = 24
記憶體對齊底層的原因是記憶體的io是以塊為單位進行的。儘管記憶體是以位元組為單位,但是大部分處理器並不是按位元組塊來訪問記憶體的.它一般會以雙位元組,四位元組,8位元組,16位元組甚至32位元組為單位來訪問記憶體,我們將上述這些訪問單位稱為記憶體訪問粒度.
現在考慮4位元組訪問粒度的處理器取int型別變數(32位系統),該處理器只能從位址為4的倍數的記憶體開始讀取資料。
假如沒有記憶體對齊機制,資料可以任意存放,現在乙個int變數存放在從位址1開始的聯絡四個位元組位址中,該處理器去取資料時,要先從0位址開始讀取第乙個4位元組塊,剔除不想要的位元組(0位址),然後從位址4開始讀取下乙個4位元組塊,同樣剔除不要的資料(5,6,7位址),最後留下的兩塊資料合併放入暫存器.這需要做很多任務作.
每個特定平台上的編譯器都有自己的預設「對齊係數」(也叫對齊模數)。gcc中預設#pragma pack(4),可以通過預編譯命令#pragma pack(n),n = 1,2,4,8,16來改變這一係數。有效對其值:是給定值#pragma pack(n)和結構體中最長資料型別長度中較小的那個。有效對齊值也叫對齊單位。
了解了上面的概念後,我們現在可以來看看記憶體對齊需要遵循的規則:
(1) 結構體第乙個成員的偏移量(offset)為0,以後每個成員相對於結構體首位址的 offset 都是該成員大小與有效對齊值中較小那個的整數倍,如有需要編譯器會在成員之間加上填充位元組。
(3) 結構體的總大小為 有效對齊值 的整數倍,如有需要編譯器會在最末乙個成員之後加上填充位元組。
提高cpu對記憶體的讀取效率。
c 類的大小
初學者在學習物件導向的程式語言時,或多或少的都些疑問,我們寫的 與最終生編譯成的 卻 大相徑庭,我們並不知道編譯器在後台做了什麼工作 這些都是由於我們僅停留在語言層的原因,所謂語言層就是教會我們一些基本的語法法則,但不會告訴我們為什麼這麼做?今天和大家談的一點感悟就是我在學習程式設計過程中的一點經驗...
C 類的大小
乙個空類class a 的大小為什麼是1,因為如果不是1,當定義這個類的物件陣列時候a objects 5 objects 0 和objects 1 就在同乙個位址處,就無法區分。單繼承 includeusing namespace std class aprivate char k 3 class...
C 類的大小
前言 c 類所占用的記憶體空間實際上是指類的例項所占用的記憶體空間。其大小是由類中的成員變數決定的 靜態成員變數除外 由於成員函式放到 區由類的各個例項共享,故成員函式對類占用記憶體大小沒有影響。具體地說,類占用記憶體大小由以下三個方面決定 1.非靜態成員變數的記憶體占用之和 2.考慮記憶體對其的問...