类大小测试(空类、带含静态和非含、虚和非虚的单继承和多继承等)

来源:互联网 发布:java下载图片怎么过滤 编辑:程序博客网 时间:2024/06/08 16:26

http://blog.csdn.net/caiguowu/article/details/6917533

本文主要是测试类大小,包括空类、带静态和不静态变量的、虚和非虚的单继承和多继承类,及类或对象的

 虚表及虚指针是否相同等情况的测试,并给出简单的解释,有不当的地方,敬请指出,一起交流与进步!

 

[cpp] view plaincopy
  1. <span style="font-size:16px;">/******************************************************************** 
  2. ** 创建人: 蔡国武 
  3. ** 日  期: 2009/5/22 15:31 
  4. ** 版  本: 1.0 
  5. ** 描  述: 测试类的大小并解释原因:  空类、带静态或虚表的类、继承和虚继承等测试     
  6.               结论: 
  7.               1: 空类的大小为1,不是0; 原因很简单,存在的,就一定会占空间。 
  8.               2: 虚表和虚函数:一个类对应一个虚表,每个对象含有一个虚函数指针(_vptr)指向虚表。 
  9.  
  10.               3: 验证了:虚继承及嵌套虚继承是否也可以共享内存的机制等测试 
  11.  
  12.  ** 应  用:  
  13. **************************** 修改记录 ****************************** 
  14. ** 修改人: 
  15. ** 日  期: 
  16. ** 描  述: 
  17. ********************************************************************/  
  18. namespace testSizeOfClass  
  19. {  
  20.  ////////  测试类的大小 start ////////  
  21.  class  CEmptyClass  
  22.  {  
  23.  };  
  24.  // sizeof(CEmptyClass) = 1  ==》空类的大小为1,不是0; 原因很简单,存在的,就一定会占空间。  
  25.    
  26.   
  27.  class  A  
  28.  {  
  29.   virtual void a(){}  
  30.  };  
  31.  // sizeof(A) = 4    // 带虚的类,因为有虚表指针,所以要占用4个字节  
  32.   
  33.    
  34.   
  35.  class  A1  
  36.  {  
  37.   virtual void a(){}  
  38.  };  
  39.  // sizeof(A1) = 4    // 带虚的类,因为有虚表指针,所以要占用4个字节  
  40.   
  41.    
  42.   
  43.  class  A2  
  44.  {  
  45.   static  int m_sNum;  
  46.  };  
  47.  // sizeof(A2) = 1   // ==》静态变量不属于某个类,是共用的  
  48.   
  49.    
  50.   
  51.  class  A3  
  52.  {  
  53.   virtual void a(){}  
  54.   static  int m_sNum;  
  55.  };  
  56.  // sizeof(A3) = 4   // ==》静态变量不属于某个类,但虚指针要占用4个字节  
  57.   
  58.    
  59.   
  60.  class  A4  
  61.  {  
  62.   bool m_bValue;  
  63.   int  m_nValue;  
  64.   static  int m_sNum;  
  65.  };  
  66.  // sizeof(A4) = 8  // 注意:内存对齐  
  67.   
  68.    
  69.   
  70.   
  71.  class B : public A  
  72.  {  
  73.  };  
  74.  // sizeof(B) = 4   
  75.   
  76.  class B1 : virtual public A // 单虚继承  
  77.  {  
  78.  };  
  79.  // sizeof(B2) = 8   // 注意:虚继承增加了一个虚指针  
  80.   
  81.  // 如果不考滤虚多继承:  
  82.  // 由B 和 B1的大小 , ==》虚继承比非虚继承大4个字节,这多出的,其实也是个虚指针,暂节不考滤,继续往下测试  
  83.   
  84.    
  85.   
  86.  class B2 : public A,public A1  // 多继承   父类都是带虚类  
  87.  {  
  88.  };  
  89.  // sizeof(B2) = 4  
  90.   
  91.  class B3 : public A1,public A2 // 多继承  父类只有一个带虚类  
  92.  {  
  93.  };  
  94.  // sizeof(B3) = 4   // 注意:虚继承增加了一个虚指针  
  95.   
  96.  // 如果不考滤虚多继承:  
  97.  // 由B、B2和B3的大小 , ==》那么一个类只有一个虚表,与多继承无关,一个对象只对应一个虚指针  
  98.  // 下面继续测试,虚多继承的情况  
  99.   
  100.    
  101.   
  102.  class B4 : public A,virtual  public A1 // 多继承, 单虚继承  
  103.  {  
  104.  };  
  105.  // sizeof(B4) = 12   // 12 = sizeof(A) + sizeof(A1) + 虚继承一个虚表指针 = 4 + 4 + 4  
  106.   
  107.  class B5 : public virtual A ,virtual  public A1 // 都是虚继承  
  108.  {  
  109.  };  
  110.  // sizeof(B5) = 12   // 12 = sizeof(A) + sizeof(A1) + 虚继承一个虚表指针 = 4 + 4 + 4  
  111.   
  112.  // 虚多继承:  
  113.  // 由B4和B5的大小 , ==》只要是虚继承,单个和多个虚继承,都只增加4个字节,也就是一个虚表指针  
  114.   
  115.    
  116.   
  117.    
  118.   
  119.    
  120.   
  121.  //class C : public A1, virtual public A1 // 出错,同一个类只能只有一种继承方式  
  122.  //{  
  123.  //};  
  124.   
  125.    
  126.   
  127.    
  128.   
  129.  class C1 :  public B, virtual public A  
  130.  {  
  131.  };  
  132.  // sizeof(C) = 12  
  133.   
  134.    
  135.   
  136.  class C2 : public B1, virtual public A  
  137.  {  
  138.  };  
  139.  // sizeof(C2) = 8 // 注意:虚继承可以共享内存,所以class C2 : public B1, virtual public A 相当于class C2 : public B1  
  140.   
  141.   
  142.  class C3 : public B1 // 验证:虚继承可以共享内存的机制, 因为 B1 已经 虚继承A  
  143.  {  
  144.  };  
  145.  // sizeof(C3) = 8 // 注意:虚继承可以共享内存的机制  
  146.   
  147.    
  148.   
  149.  class C4 : virtual public B1 // 因为 B1 已经 虚继承A  
  150.  {  
  151.  };  
  152.  // sizeof(C4) = 12 // 注意:虚继承可以共享内存的机制  
  153.   
  154.    
  155.   
  156.    
  157.   
  158. // 验证:虚继承嵌套是否也可以共享内存的机制,因为virtual B1的 虚指针也指向自身 已经 虚继承的A  
  159.   
  160.  class C5 : virtual public B1, virtual public A  
  161.   
  162.  {  
  163.  };  
  164.  // sizeof(C5) = 12 // 注意:虚继承可以共享内存,所以class C2 : public virtual B1, virtual public A 相当于class C2 : virtual public B1  
  165.   
  166.    
  167.   
  168.    
  169.   
  170.    
  171.   
  172.   
  173.  ///////  测试类的大小 end ////////  
  174.   
  175.   
  176.  void testSizeof(void)  
  177.  {  
  178.   A a1,a2;  
  179.   
  180.   // 相同类的不同对象的虚表指针 vptr 都是相同的,测试如下  
  181.   if (&a1 == &a2) // 这是成立  
  182.   {  
  183.    cout<<"相同类的不同对象的虚表指针 vptr 都是相同的";  
  184.   }  
  185.   else  
  186.   {  
  187.    cout<<"相同类的不同对象的虚表指针 vptr 是不相同的";  
  188.   }  
  189.   
  190.   
  191.   int nSizeof;  
  192.   CEmptyClass  
  193.   nSizeof = sizeof(CEmptyClass);  
  194.   
  195.   nSizeof = sizeof(A);  
  196.   nSizeof = sizeof(A1);  
  197.   nSizeof = sizeof(A2);  
  198.   nSizeof = sizeof(A3);  
  199.   nSizeof = sizeof(A4);  
  200.   nSizeof = sizeof(B);  
  201.   nSizeof = sizeof(B1);  
  202.   nSizeof = sizeof(C);  
  203.   nSizeof = sizeof(C1);  
  204.   nSizeof = sizeof(C2);  
  205.   nSizeof = sizeof(C3);  
  206.   nSizeof = sizeof(C4);  
  207.   nSizeof = sizeof(C4);  
  208.  }  
  209. }  
  210. </span>