本文主要是測試類大小,包括空類、帶靜態和不靜態變量的、虛和非虛的單繼承和多繼承類,及類或對象的
虛表及虛指針是否相同等情況的測試,並給出簡單的解釋,有不當的地方,敬請指出,一起交流與進步!
/********************************************************************
** 創建人: 蔡國武
** 日 期: 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