C 類大小的計算(對齊,繼承)

2021-06-18 19:10:32 字數 3035 閱讀 7108

先看這麼個問題——已知:

class cbase

;

那麼執行cout<<"sizeof(cbase)="《為什麼空的什麼都沒有是1呢?

類的例項化,所謂類的例項化就是在記憶體中分配一塊位址,每個例項在 記憶體中都有獨一無二的位址。同樣空類也會被例項化,所以編譯器會給空類隱含的新增乙個位元組,這樣空類例項化之後就有了 獨一無二的位址了。所以空類的sizeof為1。

第二步:

還是最初的那個類,執行結果:sizeof(cbase)=8

沒什麼說的,兩個內部變數的大小。

第三步:添個虛函式

class cbase

;

再執行:sizeof(cbase)=12

c++ 類中有虛函式的時候有乙個指向虛函式的指標(vptr),在32位系統分配指標大小為4位元組。那麼繼承類呢?

第四步:

基類就是上面的

class cchild :

public cbase

;

執行:cout<<"sizeof(cchild)="<

微策略的一道筆試題

#include using namespace std;

class a

;class b:public a

;class c:public b

;int main()

;private:

int m_ione;

}; //4

class ctwomember:virtual public conemember

//12

記憶體結構:

e8 2f 42 00 //

指標,指向乙個關於偏移量的陣列,且稱之虛基類偏移量表指標

cc cc cc cc // m_itwo

00 00 00 00 // m_ione

(虛基類資料成員)

關於閉合繼承:

#include#includeusing namespace std;

class classa

;private:

int m_ia;};

class classb:public classa

;private:

int m_ib;

};class classc:public classa

;private:

int m_ic;};

class ccomplex :public classb, public classc

;private:

int m_icomplex;

};int main()

;private:

int m_ia;};

class classb:virtual public classa

;private:

int m_ib;

};class classc:virtual public classa

;private:

int m_ic;};

class ccomplex :public classb, public classc

;private:

int m_icomplex;

};int main()

~cvirtualnull()

virtual void foo() //或者是virtual void foo()=0;都是佔4個位元組大小

};

長度:4

記憶體結構:

00 31 42 00 //

指向虛函式表的指標(虛函式表後面簡稱「虛表」)

00423100:

(虛表)

41 10 40 00 //

指向虛函式foo的指標

00401041:

e9 78 02 00 00 e9 c3 03 

…//函式foo的內容(看不懂)

評注:帶虛函式的類長度就增加了4,這個4其實就是個指標,指向虛函式表的指標,上面這個例子中虛表只有乙個函式指標,值就是「0x00401041」,指向的這個位址就是函式的入口了。

子類有新的虛函式:

class cvirtualderived: public cvirtualnull

;~cvirtualderived(){};

virtual void foo2();

private:

int m_ivd;

};長度:8

記憶體結構:

24 61 42 00 //

虛表指標

ff 00 00 00 //m_ivd

00426124:

(虛表)

23 10 40 00

50 10 40 00

評注:虛表還是只有一張,不會因為增加了新的虛函式而多出另一張來,新的虛函式的指標將新增在複製了的虛表的後面。

下面是幾個規則,供參考:

1、空類所佔空間大小為:1(位元組,下同);

2、乙個類中,虛函式本身、成員函式(包括靜態與非靜態)和靜態資料成員都是不占用類物件的儲存空間的;

3、因此乙個物件的大小≥所有非靜態成員大小的總和; 

4、當類中宣告了虛函式(不管是1個還是多個),那麼在例項化物件時,編譯器會自動在物件裡安插乙個指標vptr指向虛函式表vtable;

5、虛承繼的情況:由於涉及到虛函式表和虛基表,會同時增加乙個(多重虛繼承下對應多個)vfptr指標指向虛函式表vftable和乙個vbptr指標指向虛基表vbtable,這兩者所佔的空間大小為:8(或8乘以多繼承時父類的個數);

6、在考慮以上內容所佔空間的大小時,還要注意編譯器下的「補齊」padding的影響,即編譯器會插入多餘的位元組補齊;

7、類物件的大小=各非靜態資料成員(包括父類的非靜態資料成員但都不包括所有的成員函式)的總和+ vfptr指標(多繼承下可能不止乙個)+vbptr指標(多繼承下可能不止乙個)+編譯器額外增加的位元組

C 類大小的計算

這裡記錄一下怎麼計算類物件的大小。大概總結下,類的大小需要考慮以下內容 非靜態成員變數大小 資料對齊到多少位 有無虛函式 即需不需要指向虛函式表的指標,如果考慮繼承的情況,則還需要看繼承了多少個指向虛函式表的指標 首先我們看什麼都沒有的時候的例子 可以看到,類例項化的物件的大小為1。這是因為即使類是...

C 類 記憶體對齊和類大小理解

首先,預設的塊對齊長度是4位元組,此外也可以通過 pragma pack x 修改,同時,自己修改完之後記得使用 pragma pack 恢復預設值。此外,又分了幾種情況 1 如果有虛函式,則會儲存虛函式表的位址 僅乙個位址,4位元組或8位元組 該位址是存放在類記憶體的最開始的地方。2 如果出現比x...

C 類的大小的計算

c 的類的大小現在經常出現在筆試題目當中。那我們先看看乙個例子 程式的輸出結果 sizeof a 1 sizeof b 1 sizeof c 4 sizeof d 8 為什麼會出現這種結果呢?初學者肯定會很煩惱是嗎?類a,b明明是空類,它的大小應該為為 為什麼 編譯器輸出的結果為 呢?這就是我們剛才...