天天看点

一个类的实例化对象所占空间的大小

注意不要说类的大小,是类的对象的大小.

首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的。 

用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>

一个类的实例化对象所占空间的大小

继续阅读