http://blog.csdn.net/caiguowu/article/details/6917533
本文主要是测试类大小,包括空类、带静态和不静态变量的、虚和非虚的单继承和多继承类,及类或对象的
虚表及虚指针是否相同等情况的测试,并给出简单的解释,有不当的地方,敬请指出,一起交流与进步!
- <span style="font-size:16px;">/********************************************************************
- ** 创建人: 蔡国武
- ** 日 期: 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);
- }
- }
- </span>