程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 類大小測試(空類、帶含靜態和非含、虛和非虛的單繼承和多繼承等)

類大小測試(空類、帶含靜態和非含、虛和非虛的單繼承和多繼承等)

編輯:關於C語言

 

   本文主要是測試類大小,包括空類、帶靜態和不靜態變量的、虛和非虛的單繼承和多繼承類,及類或對象的

 

 虛表及虛指針是否相同等情況的測試,並給出簡單的解釋,有不當的地方,敬請指出,一起交流與進步!

 

 

 

/********************************************************************

** 創建人: 蔡國武

** 日  期: 2009/5/22 15:31

** 版  本: 1.0

** 描  述: 測試類的大小並解釋原因:  空類、帶靜態或虛表的類、繼承和虛繼承等測試   

              結論:

              1: 空類的大小為1,不是0; 原因很簡單,存在的,就一定會占空間。

              2: 虛表和虛函數:一個類對應一個虛表,每個對象含有一個虛函數指針(_vptr)指向虛表。

 

              3: 驗證了:虛繼承及嵌套虛繼承是否也可以共享內存的機制等測試

 

 ** 應  用:

**************************** 修改記錄******************************

** 修改人:

** 日  期:

** 描  述:

********************************************************************/

namespace testSizeOfClass

{

 ////////  測試類的大小start ////////

 class  CEmptyClass

 {

 };

 // sizeof(CEmptyClass) = 1  ==》空類的大小為1,不是0; 原因很簡單,存在的,就一定會占空間。

 

 

 class  A

 {

  virtual void a(){}

 };

 // sizeof(A) = 4    // 帶虛的類,因為有虛表指針,所以要占用4個字節

 

 

 

 class  A1

 {

  virtual void a(){}

 };

 // sizeof(A1) = 4    // 帶虛的類,因為有虛表指針,所以要占用4個字節

 

 

 

 class  A2

 {

  static  int m_sNum;

 };

 // sizeof(A2) = 1   // ==》靜態變量不屬於某個類,是共用的

 

 

 

 class  A3

 {

  virtual void a(){}

  static  int m_sNum;

 };

 // sizeof(A3) = 4   // ==》靜態變量不屬於某個類,但虛指針要占用4個字節

 

 

 

 class  A4

 {

  bool m_bValue;

  int  m_nValue;

  static  int m_sNum;

 };

 // sizeof(A4) = 8  // 注意:內存對齊

 

 

 

 

 class B : public A

 {

 };

 // sizeof(B) = 4

 

 class B1 : virtual public A // 單虛繼承

 {

 };

 // sizeof(B2) = 8   // 注意:虛繼承增加了一個虛指針

 

 // 如果不考濾虛多繼承:

 // 由B 和B1的大小 ,==》虛繼承比非虛繼承大4個字節,這多出的,其實也是個虛指針,暫節不考濾,繼續往下測試

 

 

 

 class B2 : public A,public A1  // 多繼承   父類都是帶虛類

 {

 };

 // sizeof(B2) = 4

 

 class B3 : public A1,public A2 // 多繼承  父類只有一個帶虛類

 {

 };

 // sizeof(B3) = 4   // 注意:虛繼承增加了一個虛指針

 

 // 如果不考濾虛多繼承:

 // 由B、B2和B3的大小 ,==》那麼一個類只有一個虛表,與多繼承無關,一個對象只對應一個虛指針

 // 下面繼續測試,虛多繼承的情況

 

 

 

 class B4 : public A,virtual  public A1 // 多繼承, 單虛繼承

 {

 };

 // sizeof(B4) = 12   // 12 = sizeof(A) + sizeof(A1) + 虛繼承一個虛表指針= 4 + 4 + 4

 

 class B5 : public virtual A ,virtual  public A1 // 都是虛繼承

 {

 };

 // sizeof(B5) = 12   // 12 = sizeof(A) + sizeof(A1) + 虛繼承一個虛表指針= 4 + 4 + 4

 

 // 虛多繼承:

 // 由B4和B5的大小 ,==》只要是虛繼承,單個和多個虛繼承,都只增加4個字節,也就是一個虛表指針

 

 

 

 

 

 

 

 //class C : public A1, virtual public A1 // 出錯,同一個類只能只有一種繼承方式

 //{

 //};

 

 

 

 

 

 class C1 :  public B, virtual public A

 {

 };

 // sizeof(C) = 12

 

 

 

 class C2 : public B1, virtual public A

 {

 };

 // sizeof(C2) = 8 // 注意:虛繼承可以共享內存,所以class C2 : public B1, virtual public A 相當於class C2 : public B1

 

 

 class C3 : public B1 // 驗證:虛繼承可以共享內存的機制, 因為B1 已經 虛繼承A

 {

 };

 // sizeof(C3) = 8 // 注意:虛繼承可以共享內存的機制

 

 

 

 class C4 : virtual public B1 // 因為B1 已經 虛繼承A

 {

 };

 // sizeof(C4) = 12 // 注意:虛繼承可以共享內存的機制

 

 

 

 

 

// 驗證:虛繼承嵌套是否也可以共享內存的機制,因為virtual B1的 虛指針也指向自身 已經 虛繼承的A

 

 class C5 : virtual public B1, virtual public A

 

 {

 };

 // sizeof(C5) = 12 // 注意:虛繼承可以共享內存,所以class C2 : public virtual B1, virtual public A 相當於class C2 : virtual public B1

 

 

 

 

 

 

 

 

 ///////  測試類的大小end ////////

 

 

 void testSizeof(void)

 {

  A a1,a2;

 

  // 相同類的不同對象的虛表指針vptr 都是相同的,測試如下

  if (&a1 == &a2) // 這是成立

  {

   cout<<"相同類的不同對象的虛表指針vptr 都是相同的";

  }

  else

  {

   cout<<"相同類的不同對象的虛表指針vptr 是不相同的";

  }

 

 

  int nSizeof;

  CEmptyClass

  nSizeof = sizeof(CEmptyClass);

 

  nSizeof = sizeof(A);

  nSizeof = sizeof(A1);

  nSizeof = sizeof(A2);

  nSizeof = sizeof(A3);

  nSizeof = sizeof(A4);

  nSizeof = sizeof(B);

  nSizeof = sizeof(B1);

  nSizeof = sizeof(C);

  nSizeof = sizeof(C1);

  nSizeof = sizeof(C2);

  nSizeof = sizeof(C3);

  nSizeof = sizeof(C4);

  nSizeof = sizeof(C4);

 }

}

 

作者caiguowu

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved