注:本文測試實例使用的編譯器版本爲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類中須要同時存放這兩個指針。