天天看點

關于類的sizeof()

1、  空類的大小為1(沒有資料成員的類).why?C++編譯器不允許對象的大小為0,因為記憶體大小為0的類根本沒地方存儲,為了找到這個類編譯器通常會添加一個大小為1的預設的成員(char類型的)。如果有自定義的變量,那麼自定義的變量将替換掉這個變量。

2、  簡單類。簡單類要考慮記憶體對齊的情況,還要考慮靜态資料不是sizeof()計算的範圍。因為它存放在全局資料區,而不是棧裡。

3、  帶虛函數的類。帶虛函數的類(不管有幾個虛函數,因為子類與父類的虛函數都存放在同一個虛函數表中)裡面有一個虛函數指針,是以要在簡單類的基礎上加上4才可以。

4、  普通的繼承:代碼如下classA{public:  int a;char b;}  class B:public A{ public: char c},這裡的sizeof(B)會根據編譯器的不同而不同,比如codeblocks為8,而vs2010為12. 一般說來普通的繼承的大小為sizeof(基類)+sizeof(派生類),然後再考慮對齊的問題,記憶體大小應該類中最大資料元素所占記憶體的整數倍,(具體要看編譯器的實作原理).

5、  子類虛繼承父類。普通虛繼承(不包含虛函數):sizeof(子類)=sizeof(父類)+sizeof(子類的資料成員)+sizeof(虛表指針)。對于含有虛函數的虛繼承,子類和父類的虛函數存放在不同虛表中。但是在具體的實作上不同的編譯器還是不同的,如:class A{ public: int a;};

class B:virtual public A{public:int a;  virtual void f(){}  }; sizeof(B)在codeblocks中是12,而在vs2010中是16. 又如:class A{public: int a; virtual void set(){}  };classB:virtual public A{public:int a;  virtualvoid set(){}  }; sizeof(B) 在codeblocks中是16,而在vs2010中是20.

6、簡單的多重繼承:sizeof(子類)=sizeof(父類1)+sizeof(父類2)+……+sizeof(父類n).如果是多重虛繼承,虛繼承存在的意義就是為了減少記憶體開銷和二義性,實作對象共享。例如:

class A{public : int a;  }; class B:virtual public A{ public:int b; };class C:virtual public A{ public:int c}; class D:public B,public A{ public: int d;};  得到的sizeof(D)的大小為20

7、  一個小例子:classA{}; class B{};  class{  public: virtual voif f(){} }: public D:publicB,public C{}; cout<<sizeof(A)<<” “<<sizeof(B)<<” “<<sizeof(C)<<”  “<<sizeof(D)<<endl;  根據編譯器不同可能得到的是1,1,4,4 或者1,1,4,8.  不管類是否為空類都可以執行個體化,每一個被執行個體化的類都有獨一無二的位址,即我們總是可以找到用位址找到它的。

繼續閱讀