类和对象占多少空储空间?

类或者对象的大小可以用sizeof运算符算出,即sizeof(object_name)。可是sizeof(object_name)的值与其成员的大小是什么关系呢,答案是:一个对象的大小>=所有非静态成员大小的总和。

 

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

 

1) C++对象模型本身 

 

对有虚函数的类来说,必须为它的对象提供运行时类型信息(RTTIRun-Time Type Information)和关于虚函数表的信息,常见的做法是在对象中放置一个指向虚函数表的指针,此外,为了支持RTTI,许多编译器都把该类型信息放在虚函数表中。但是,是否必须采用这种实现方法,C++标准没有规定,主流编译器均采用的一种方案。 

 

2) 字节对齐

因为对于大多数CPU来说,CPU字长的整数倍操作起来更快,因此对于这些成员加起来如果不够这个整数倍,有可能编译器会插入多余的内容凑足这个整数倍,此外,有时候相邻的成员之间也有可能因为这个目的被插入空白,这个叫做补齐(padding)。所以,C++标准紧紧规定成员的排列按照类定义的顺序,但是不要求在存储器中是紧密排列的。 

 

基于上述两点,可以说用sizeof对类名操作,得到的结果是该类的对象在存储器中所占据的字节大小,由于静态成员变量不在对象中存储,因此这个结果等于各非静态数据成员(不包括成员函数)的总和加上编译器额外增加的字节。后者依赖于不同的编译器实现,C++标准对此不做任何保证。 

 

C++标准规定类的大小不为0,空类的大小为1,当类不包含虚函数和非静态数据成员时,其对象大小也为1

 

如果在类中声明了虚函数(不管是1个还是多个),那么实例化对象时,编译器会自动在对象里放置一个指针指向虚函数表VTable,它是实现多态的关键点。但虚函数本身和其他成员函数一样,是不占用对象的空间的。

 

我们来看下面一个例子:

  1. #include <iostream>  
  2. using namespace std;  
  3. class   A     
  4.  {     
  5.  };     
  6.   
  7. class   B     
  8.  {     
  9.     char   ch;     
  10.     void   func(){  }     
  11.  };  
  12.    
  13. class   C     
  14. {     
  15.     char   ch1;             //占用1字节  
  16.     char   ch2;             //占用1字节  
  17.     virtual   void   func(){ }     
  18. };  
  19.     
  20. class   D     
  21. {     
  22.     int   in;     
  23.     virtual   void   func(){}    
  24. };     
  25.   
  26. int  main()     
  27. {     
  28.     A   a;   
  29.     B   b;  
  30.     C   c;   
  31.     D   d;   
  32.     cout<<sizeof(a)<<endl;//result=1  
  33.     cout<<sizeof(b)<<endl;//result=1  
  34.     cout<<sizeof(c)<<endl;//result=8     
  35.     cout<<sizeof(d)<<endl;//result=8     
  36. }   

综上所述:

虚函数、成员函数[包括静态与非静态]、和静态数据成员都是不占用对象的存储空间的

对象大小  =  vptr(可能不止一个)   +   所有非静态数据成员大小   +   因对齐而多占的字节


展开阅读全文

没有更多推荐了,返回首页