轉載博客:轉載地址https://www.cnblogs.com/JingHuanXiao/p/6080726.html
一個空的class在內存中多少字節?如果加入一個成員函數后是多大?這個成員函數存儲在內存中什么部分?
一個Class對象需要占用多大的內存空間。最權威的結論是:
*非靜態成員變量總合。
*加上編譯器為了CPU計算,作出的數據對齊處理。
*加上為了支持虛函數,產生的額外負擔。
介紹完了理論知識后,再看看再找一個例子看看(注:一下所有結果都是在VC6.0 開發環境中得出的結論)
一、空類的Size

1 class Car 2 { 3 }; 4 5 void main() 6 { 7 int size = 0; 8 Car objCar; 9 size = sizeof(objCar); 10 printf("%s %d /r", "Class Car Size:", size); 11 } 12 13 輸出結果:Class Car Size:1
這是為何呢?我想對於這個問題,不僅是剛入行不久的開發新手,就算有過幾年以上C++開發經驗的開發人員也未必能說清楚這個。
編譯器在執行Car objCar;這行代碼后需要,作出一個Class Car的Object。並且這個Object的地址還是獨一無二的,於是編譯器就會給空類創建一個隱含的一個字節的空間。
二、只有成員變量的Size

1 class Car 2 { 3 private: 4 int nLength; 5 int nWidth; 6 }; 7 8 void main() 9 { 10 int size = 0; 11 Car objCar; 12 size = sizeof(objCar); 13 printf("%s %d /r", "Class Car Size:", size); 14 } 15 16 輸出結果:Class Car Size:8
這個結果很多開發人員都清楚。在32位系統中,整型變量占4個字節。這里Class Car中含有兩個整型類型的成員變量,所以Class Size是8。

1 class Car 2 { 3 private: 4 int nLength; 5 int nWidth; 6 static int sHigh; 7 }; 8 9 void main() 10 { 11 int size = 0; 12 Car objCar; 13 size = sizeof(objCar); 14 printf("%s %d /r", "Class Car Size:", size); 15 } 16 輸出結果:Class Car Size:8
我們這次在Class Car中添加了一個靜態成員變量,但是Class Size仍然是8個字節。這正好符合了,結論中的第一條:非靜態成員變量總合。

1 class Car 2 { 3 private: 4 char chLogo 5 int nLength; 6 int nWidth; 7 static int sHigh; 8 }; 9 10 void main() 11 { 12 int size = 0; 13 Car objCar; 14 size = sizeof(objCar); 15 printf("%s %d /r", "Class Car Size:", size); 16 } 17 輸出結果:Class Car Size:12
在類中又插入了一個字符型變量,結果Class Size變成了12。這個就是編譯器額外添加3個字符變量,做數據對齊處理,為了是提高CPU的計算速度。編譯器額外添加的東西我們是無法看見的。這也符合了結論中的第二條:加上編譯器為了CPU計算,作出的數據對齊處理。
既然,我們這樣定義類成員數據編譯器會額外的增加空。那么,我們何不在定義類的時候就考慮到數據對齊的問題,可以多定義出3個字符類型變量作為預留變量,既能滿足數據對齊的要求,也給自己的程序添加了一些可擴展的空間。
三、只有成員函數的Size

1 class Car 2 { 3 public: 4 Car(){}; 5 ~Car(){}; 6 public: 7 void Fun(){}; 8 }; 9 10 void main() 11 { 12 int size = 0; 13 Car objCar; 14 size = sizeof(objCar); 15 printf("%s %d /r", "Class Car Size:", size); 16 } 17 輸出結果:Class Car Size:1
噢,這是怎么回事兒呢?再做一個實驗看看。

1 class Car 2 { 3 public: 4 Car(){}; 5 ~Car(){}; 6 public: 7 void Fun(){}; 8 private: 9 int nLength; 10 int nWidth; 11 }; 12 13 void main() 14 { 15 int size = 0; 16 Car objCar; 17 size = sizeof(objCar); 18 printf("%s %d /r", "Class Car Size:", size); 19 } 20 輸出結果:Class Car Size:8
這次應該很清楚的了。函數是不占用類空間的。第一個例子中的Size為1個字節,正是編譯器為類創建一個隱含的一個字節的空間

1 class Car 2 { 3 public: 4 Car(){}; 5 virtual ~Car(){}; 6 public: 7 void Fun(){}; 8 }; 9 10 void main() 11 { 12 int size = 0; 13 Car objCar; 14 size = sizeof(objCar); 15 printf("%s %d /r", "Class Car Size:", size); 16 } 17 輸出結果:Class Car Size:4
這次,讓析構函數為虛函數,看到了Class Size為4。這正是指向Virtual Table的指針vptr的Size。這正好符合了,結論中的第三條:加上為了支持虛函數,產生的額外負擔。