C++中各類類的大小

注:本文測試實例使用的編譯器版本爲clang-703.0.29,系統int長度爲4字節,指針長度爲8字節。html

1. 空類函數

class A {};

空類sizeof的結果爲1,爲何不是0呢?由於C++標準規定兩個不一樣實例的內存地址必須不一樣(戳這裏),因此用這一個字節來佔用不一樣的內存地址,讓空類的兩個實例能夠相互區分。而大多數編譯器支持空基類優化(Empty Base Class Optimization, EBCO),即從空基類中派生出來的類並不會增長1字節,如:測試

class B : A {
  int a;
};

sizeof(B)的結果爲4而不是5或8。優化

2. 帶靜態數據成員的類spa

class C {
  int a;
  static int b;
};

sizeof(C)結果爲4,靜態數據成員被存放在類對象以外。指針

3. 帶非虛函數成員的類code

class D {
  public:
    void func1() {}
    static void func2() {}
};

sizeof(D)結果爲1,不管是普通成員函數仍是靜態成員函數都被存放在類對象以外。htm

4. 帶虛函數成員的類對象

class E {
  public:
    virtual void func() {}
};

sizeof(E)結果爲8,帶虛函數成員的類對象會包含一個指向該類的virtual table的指針。blog

5. 對齊規則

class F {
  char a;
  int  b;
};

sizeof(F)的結果爲8而不是5,因爲F的最大對齊值爲4(int),所以a和b之間被補齊3字節。

6. 普通派生類

class G : public C {
  int a;
};

sizeof(G)的結果爲8,派生類會存放基類中非靜態數據成員(C中的a)的副本。

7. 基類帶虛函數的派生類

class H : public E {};

sizeof(H)結果爲8,因爲基類中帶虛函數,派生類中也必須保存一個指向派生類的virtual table的指針。

8. 多重繼承的派生類

class I : public B, public C {};

sizeof(I)結果爲8,B和C中非靜態數據成員長度以及是否須要指向virtual table的指針的狀況加和。

9. 多重繼承下的對齊規則

class J : public B, public F {
  char a;
};

sizeof(J)結果爲16,B、F和J類中共有兩個int兩個char,對齊後4*4結果爲16。

10. 虛繼承的派生類

class K : virtual public A {};

class L : virtual public B {};

sizeof(K)的結果爲8,派生類中會存放一個指向虛繼承基類惟一實例的指針。sizeof(L)的結果爲16,由於對齊規則int被補齊。注意虛繼承和虛函數是兩個徹底不一樣的概念,它們之間沒有直接聯繫。

class M : virtual public A {};

class N : public K, public M {};

sizeof(N)的結果爲16,雖然K類和M類中的虛繼承指針指向了同一個基類實例,但它們是不一樣的指針,N類中須要同時存放這兩個指針。

相關文章
相關標籤/搜索