C 中類物件的記憶體布局和占用空間

2021-08-01 10:49:42 字數 3102 閱讀 7105

很多c++書籍中都介紹過,乙個class物件需要占用多大的記憶體空間。最權威的結論是:

*非靜態成員變數總合。

*加上編譯器為了cpu計算,作出的資料對齊處理。

*加上為了支援虛函式,產生的額外負擔。

介紹完了理論知識後,再看看再找乙個例子看看(注:一下所有結果都是在vc6.0 開發環境中得出的結論)

一、空類的size

class car ;

void main()

輸出結果:class car size:1

這是為何呢?我想對於這個問題,不僅是剛入行不久的開發新手,就算有過幾年以上c++開發經驗的開發人員也未必能說清楚這個。

編譯器在執行car objcar;這行**後需要,作出乙個class car的object。並且這個object的位址還是獨一無二的,於是編譯器就會給空類建立乙個隱含的乙個位元組的空間。

二、只有成員變數的size

class car ;

void main()

輸出結果:class car size:8

這個結果很多開發人員都清楚。在32位系統中,整型變數佔4個位元組。這裡class car中含有兩個整型型別的成員變數,所以class size是8。

class car ;

void main()

輸出結果:class car size:8

我們這次在class car中新增了乙個靜態成員變數,但是class size仍然是8個位元組。這正好符合了,結論中的第一條:非靜態成員變數總合。

class car ;

void main()

輸出結果:class car size:12

在類中又插入了乙個字元型變數,結果class size變成了12。這個就是編譯器額外新增3個字元變數,做資料對齊處理,為了是提高cpu的計算速度。編譯器額外新增的東西我們是無法看見的。這也符合了結論中的第二條:加上編譯器為了cpu計算,作出的資料對齊處理。

既然,我們這樣定義類成員資料編譯器會額外的增加空。那麼,我們何不在定義類的時候就考慮到資料對齊的問題,可以多定義出3個字元型別變數作為預留變數,既能滿足資料對齊的要求,也給自己的程式新增了一些可擴充套件的空間。

三、只有成員函式的size

class car ;

~car(){};

public:

void fun(){}; };

void main()

輸出結果:class car size:1

噢,這是怎麼回事兒呢?再做乙個實驗看看。

class car ;

~car(){};

public:

void fun(){};

private:

int nlength;

int nwidth; };

void main()

輸出結果:class car size:8

這次應該很清楚的了。函式是不占用類空間的。第乙個例子中的size為1個位元組,正是編譯器為類建立乙個隱含的乙個位元組的空間

class car ;

virtual ~car(){};

public:

void fun(){}; };

void main()

輸出結果:class car size:4

這次,讓析構函式為虛函式,看到了class size為4。這正是指向virtual table的指標vptr的size。這正好符合了,結論中的第三條:加上為了支援虛函式,產生的額外負擔。

到此為止,乙個class object究竟占用多少記憶體空間,已經完全說清楚了。但是,這只是針對單獨類,或者說是基類適用。對於子類,卻不一樣了。有興趣的朋友可以做一些實驗。

《c++ 類裡面,函式占用儲存空間問題 》

先看兩段**:

**段1:

class a ;

inr main()

輸出結果:

size of a =1

**段2:

class a ;

inr main()

輸出結果:

size of a =1

物件的大小是它的資料成員所佔儲存空間之和,就和結構體一樣。類中的函式是所有該類物件通用的方法,不算作物件的成員,因此也不算在物件的儲存空間內

問題:類裡面不管有多少個函式,這個類的物件只佔1個位元組的記憶體。這個位元組的記憶體的內容是什麼?是指標嗎?指標不是佔4個位元組嗎?

當類中類有定義任何變數的時候,類的物件都是1個位元組的,當類中沒有任何變數的時候,這個類裡沒有任何真正的成員變數,所以大小應該是0,但0大小不好在記憶體中定位乙個位址,所以,就規定它大小為0的物件要佔一位元組空間,以便讓它擁有乙個合法的位址。如果是有派生類的,還有考慮到記憶體對齊的問題的。

另外涉及到虛函式的話又不一樣了。如

class a ;

如果sizeof(a)的話,得出的是4。

原因是涉及到虛函式的實現問題。

class class1 ;

class1物件例項

通過vptr指標找到虛函式表

vptr

m_data1

m_data2

vtable(虛函式表)

(*vfunc1)()

(*vfunc2)()

(*vfunc3)()

class1::vfunc1()

class1::vfunc2()

class1::vfunc3()

所以回到原來的問題,a中只有乙個或者幾個虛函式的話,沒有成員變數,那麼類a相當於含有乙個vptr指向虛函式表的指標,所以sizeof(a)=4。

還有一點,如

class b ;

class b2 ;

class c:public b ;

class d:public virtual b ;

class e:public b,public b2 ;

sizeof(b) = 1;   sizeof(b2) = 1;  sizeof(c) = 1;  sizeof(d) = 4;  sizeof(e) = 1;

空類所佔空間為一(上文以解釋),單一繼承的空類空間也是1,多重繼承的空類空間還是1,但是虛繼承涉及到虛表(虛指標),所以sizeof(d)=4。

from:

C 類物件記憶體布局

本文通過分析記憶體布局來了解編譯器對類的記憶體布局的安排。分析方法為先貼出 在給出相應記憶體的內容,最後給出分析結果。以下執行環境為vs2005,不同編譯器實現可以不一樣 一般是因為c 標準並未要求 具體可參見 深度探索c 物件模型 單一繼承 如下 class a int a class b pub...

C 中類的物件所佔記憶體空間總結

類所佔記憶體的大小是由成員變數 靜態變數除外 決定的,成員函式 這是籠統的說,後面會細說 是不計算在內的。摘抄部分 成員函式還是以一般的函式一樣的存在。a.fun 是通過fun a.this 來呼叫的。所謂成員函式只是在名義上是類裡的。其實成員函式的大小不在類的物件裡面,同乙個類的多個物件共享函式 ...

C 物件模型和布局(三種經典類物件記憶體布局)

侯捷翻譯的 深度探索c 物件模型 一書中,對c 物件模型進行了三種典型模型劃分,分別為簡單物件模型 a object model 驅動物件模型 a table drive object model c 物件模型 the c object model 本文以及之後的部落格主要總結的都是最後乙個c 物件...