天天看點

一個類的執行個體化對象所占空間的大小

注意不要說類的大小,是類的對象的大小.

首先,類的大小是什麼?确切的說,類隻是一個類型定義,它是沒有大小可言的。 

用sizeof運算符對一個類型名操作,得到的是具有該類型實體的大小。 

如果 

class a; 

a obj; 

那麼sizeof(a)==sizeof(obj) 

那麼sizeof(a)的大小和成員的大小總和是什麼關系呢,很簡單,一個對象的大小大于等于所有非靜态成員大小的總和。 

為什麼是大于等于而不是正好相等呢?超出的部分主要有以下兩方面: 

1) c++對象模型本身 

對于具有虛函數的類型來說,需要有一個方法為它的實體提供類型資訊(rtti)和虛函數入口,常見的方法是建立一個虛函數入口表,這個表可為相同類型的對象共享,是以對象中需要有一個指向虛函數表的指針,此外,為了支援rtti,許多編譯器都把該類型資訊放在虛函數表中。但是,是否必須采用這種實作方法,c++标準沒有規定,但是這幾戶是主流編譯器均采用的一種方案。 

2) 編譯器優化 

因為對于大多數cpu來說,cpu字長的整數倍操作起來更快,是以對于這些成員加起來如果不夠這個整數倍,有可能編譯器會插入多餘的内容湊足這個整數倍,此外,有時候相鄰的成員之間也有可能因為這個目的被插入空白,這個叫做“補齊”(padding)。是以,c++标準緊緊規定成員的排列按照類定義的順序,但是不要求在存儲器中是緊密排列的。 

基于上述兩點,可以說用sizeof對類名操作,得到的結果是該類的對象在存儲器中所占據的位元組大小,由于靜态成員變量不在對象中存儲,是以這個結果等于各非靜态資料成員(不包括成員函數)的總和加上編譯器額外增加的位元組。後者依賴于不同的編譯器實作,c++标準對此不做任何保證。

c++标準規定類的大小不為0,空類的大小為1,當類不包含虛函數和非靜态資料成員時,其對象大小也為1。

如果在類中聲明了虛函數(不管是1個還是多個),那麼在執行個體化對象時,編譯器會自動在對象裡安插一個指針指向虛函數表vtable,在32位機器上,一個對象會增加4個位元組來存儲此指針,它是實作面向對象中多态的關鍵。而虛函數本身和其他成員函數一樣,是不占用對象的空間的。

我們來看下面一個例子:(此例子在visual c++編譯器中編譯運作)

<code>#include &lt;iostream&gt;</code>

<code>using</code> <code>namespace</code> <code>std;</code>

<code>class</code>   <code>a  </code>

<code>{  </code>

<code>};  </code>

<code>class</code>   <code>b  </code>

<code>char</code>   <code>ch;  </code>

<code>void</code>   <code>func()  </code>

<code>}  </code>

<code>class</code>   <code>c  </code>

<code>char</code>   <code>ch1;   </code><code>//占用1位元組</code>

<code>char</code>   <code>ch2;  </code><code>//占用1位元組</code>

<code>virtual</code>   <code>void</code>   <code>func()  </code>

<code>class</code>   <code>d  </code>

<code>int</code>   <code>in;  </code>

<code>void</code>   <code>main()  </code>

<code>a   a;</code>

<code>b   b;</code>

<code>c   c;</code>

<code>d   d;</code>

<code>cout&lt;&lt;</code><code>sizeof</code><code>(a)&lt;&lt;endl;</code><code>//result=1  </code>

<code>cout&lt;&lt;</code><code>sizeof</code><code>(b)&lt;&lt;endl;</code><code>//result=1   //對象c擴充為2個字,但是對象b為什麼沒擴充為1個字呢?大家幫忙解決</code>

<code>cout&lt;&lt;</code><code>sizeof</code><code>(c)&lt;&lt;endl;</code><code>//result=8  </code>

<code>//對象c實際上隻有6位元組有用資料,但是按照上面第二點編譯器優化,編譯器将此擴充為兩個字,即8位元組</code>

<code>cout&lt;&lt;</code><code>sizeof</code><code>(d)&lt;&lt;endl;</code><code>//result=8  </code>

<code>} </code>

  

綜上所述:

一個類中,虛函數、成員函數(包括靜态與非靜态)和靜态資料成員都是不占用類對象的存儲空間的。

對象大小=   vptr(可能不止一個)   +   所有非靜态資料成員大小   +   aligin位元組大小(依賴于不同的編譯器)

<code>class</code> <code>demo1{</code>

<code>};</code>

<code>class</code> <code>demo2{</code>

<code>    </code><code>static</code> <code>int</code> <code>num;</code>

<code>class</code> <code>demo3{</code>

<code>    </code><code>virtual</code> <code>int</code> <code>print(){}</code>

<code>    </code><code>virtual</code> <code>int</code> <code>print1(){}</code>

<code>class</code> <code>demo4{</code>

<code>    </code><code>void</code> <code>print(){}</code>

<code>    </code><code>static</code> <code>void</code> <code>print1(){}</code>

<code>class</code> <code>demo5{</code>

<code>    </code><code>char</code> <code>a;</code>

<code>int</code> <code>_tmain(</code><code>int</code> <code>argc, _tchar* argv[])</code>

<code>    </code><code>cout&lt;&lt;</code><code>"空類的大小為:"</code><code>&lt;&lt;</code><code>sizeof</code><code>(demo1)&lt;&lt;endl;</code>

<code>    </code><code>//當類不包含虛函數和非靜态資料成員時,其對象大小也為1。</code>

<code>    </code><code>cout&lt;&lt;</code><code>"當類不包含虛函數和非靜态資料成員時,其對象大小也為:"</code><code>&lt;&lt;</code><code>sizeof</code><code>(demo2)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"與類中虛函數的個數無關"</code><code>&lt;&lt;</code><code>sizeof</code><code>(demo3)&lt;&lt;endl;   </code><code>//大小是4,與類中虛函數的個數無關,</code>

<code>    </code><code>cout&lt;&lt;</code><code>"成員函數(靜态和非靜态)也不占用類對象的存儲空間"</code><code>&lt;&lt;</code><code>sizeof</code><code>(demo4)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>sizeof</code><code>(demo5)&lt;&lt;endl;</code>

<code>    </code><code>demo5 d;</code>

<code>    </code><code>cout&lt;&lt;</code><code>sizeof</code><code>(d)&lt;&lt;endl;</code>

<code>    </code><code>return</code> <code>0;</code>

<code>}</code>

一個類的執行個體化對象所占空間的大小

繼續閱讀