关于sizeof
简单归纳:
1.(无虚函数或有虚函数的)空类的sizeof是1,它的实例化也需要独一无二的空间地址
2.无虚函数的类的sizeof是内部成员大小之和
3.有虚函数的类的sizeof是内部成员大小之和再加4,这样的类有一个指向虚函数表的指针
4.子类的sizeof是基类的大小加上子类成员大小,若子类有新的虚函数也是如此
5.有静态成员的类,静态成员不占类的大小
6.类的虚继承会多出一个指针,指向的是虚基类成员偏移量数组
代码示例:
1 #include <QCoreApplication> 2 #include <QTextStream> 3 #include <stdio.h> 4 QTextStream cin(stdin, QIODevice::ReadOnly); 5 QTextStream cout(stdout, QIODevice::WriteOnly); 6 class CBase 7 { 8 /*类的实例化就是在内存中分配一块地址,空类也会被实例化, 9 所以编译器给空类隐含的添加一个字节,这样空类实例化后就有了一个独一无二的地址了, 10 所以空类的sizeof为1 11 */ 12 }; 13 class CBase2 14 { 15 int a;//内部变量的大小之和 16 char* p; 17 }; 18 class CBase3 19 { 20 public: 21 CBase3(void); 22 virtual ~CBase3(void);//c++类中有虚函数的时候有一个指向虚函数的指针vptr 23 private: 24 int a; 25 char *p; 26 }; 27 class CChild: public CBase2 28 { 29 public: 30 CChild(void); 31 ~CChild(void); 32 private: 33 int b;//继承类的sizeof是 34 }; 35 //虚拟继承(相当于添加了一个接口) 36 //virtual虚继承让长度增加了4,其实是多了一个指针,它指向一个关于虚基类偏移量的数组,偏移量是关于虚基类数据成员的偏移量 37 //注意,这个指针不是虚函数表指针 38 class COneMember 39 { 40 public: 41 COneMember(int iValue=0){m_iOne = iValue;}; 42 private: 43 int m_iOne; 44 }; 45 class CTwoMember : virtual public COneMember 46 { 47 private: 48 int m_iTwo; 49 }; 50 //关于闭合继承 51 class A 52 { 53 public: 54 A(int iValue=1){m_iA = iValue;}; 55 private: 56 int m_iA; 57 }; 58 class B :virtual public A 59 { 60 public: 61 B(int iValue=2){m_iB = iValue;}; 62 private: 63 int m_iB; 64 }; 65 class C : virtual public A 66 { 67 public: 68 C(int iValue=3){m_iC = iValue;}; 69 private: 70 int m_iC; 71 }; 72 class Complex : public B, public C 73 { 74 public: 75 Complex(int iValue=4){m_iComplex = iValue;}; 76 private: 77 int m_iComplex; 78 }; 79 //虚空类为4,非虚空类为1 80 class EVirtual 81 { 82 public: 83 EVirtual(){printf("Construct/n");} 84 virtual ~EVirtual(){ printf("Destruct/n");} 85 }; 86 //静态成员不会占用类的大小 87 class CStaticNull 88 { 89 public: 90 CStaticNull(){}; 91 static void Foo(){printf("Foo/n");}; 92 static int m_iValue; 93 }; 94 //虚函数:子类有新的虚函数,虚表还是只有一张 95 class CVirtualNull 96 { 97 public: 98 CVirtualNull(); 99 virtual ~CVirtualNull(); 100 virtual Foo(); 101 }; 102 class CVirtualDerived : public CVirtualNull 103 { 104 public: 105 virtual FooDerived(); 106 }; 107 int main(int argc, char *argv[]) 108 { 109 QCoreApplication a(argc, argv); 110 cout<<"sizeof(CBase)="<<sizeof(CBase)<<endl; 111 cout<<"sizeof(CBase2)="<<sizeof(CBase2)<<endl; 112 cout<<"sizeof(CBase3)="<<sizeof(CBase3)<<endl; 113 cout<<"sizeof(CChild)="<<sizeof(CChild)<<endl; 114 cout<<"sizeof(CTwoMember)="<<sizeof(CTwoMember)<<endl;//12 115 cout<<"sizeof(Complex)="<<sizeof(Complex)<<endl; 116 cout<<"sizeof(EVirtual)="<<sizeof(EVirtual)<<endl; 117 cout<<"sizeof(CStaticNull)="<<sizeof(CStaticNull)<<endl; 118 cout<<"sizeof(CVirtualDerived)="<<sizeof(CVirtualDerived)<<endl; 119 return a.exec(); 120 }