關於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 }
View Code
相關文章
相關標籤/搜索