程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++中類對象的內存布局和占用空間

C++中類對象的內存布局和占用空間

編輯:C++入門知識

很多C++書籍中都介紹過,一個Class對象需要占用多大的內存空間。最權威的結論是:
*非靜態成員變量總合。

*加上編譯器為了CPU計算,作出的數據對齊處理。

*加上為了支持虛函數,產生的額外負擔。

 

介紹完了理論知識後,再看看再找一個例子看看(注:一下所有結果都是在VC6.0 開發環境中得出的結論)

一、空類的Size

class Car

{

};

 

void main()

{

       int size = 0;

       Car objCar;

       size = sizeof(objCar);

       printf("%s %d /r", "Class Car Size:", size);

}

 

輸出結果:Class Car Size:1

 

這是為何呢?我想對於這個問題,不僅是剛入行不久的開發新手,就算有過幾年以上C++開發經驗的開發人員也未必能說清楚這個。

編譯器在執行Car objCar;這行代碼後需要,作出一個Class Car的Object。並且這個Object的地址還是獨一無二的,於是編譯器就會給空類創建一個隱含的一個字節的空間。

 

 

二、只有成員變量的Size

class Car

{

private:

       int nLength;

       int nWidth;

};

void main()

{

       int size = 0;

       Car objCar;

       size = sizeof(objCar);

       printf("%s %d /r", "Class Car Size:", size);

}

輸出結果:Class Car Size:8

這個結果很多開發人員都清楚。在32位系統中,整型變量占4個字節。這裡Class Car中含有兩個整型類型的成員變量,所以Class Size是8。

 

class Car

{

private:

       int nLength;

       int nWidth;

       static int sHigh;

};

void main()

{

       int size = 0;

       Car objCar;

       size = sizeof(objCar);

       printf("%s %d /r", "Class Car Size:", size);

}

輸出結果:Class Car Size:8

我們這次在Class Car中添加了一個靜態成員變量,但是Class Size仍然是8個字節。這正好符合了,結論中的第一條:非靜態成員變量總合。

class Car

{

private:

       char chLogo

       int nLength;

       int nWidth;

       static int sHigh;

};

 

void main()

{

       int size = 0;

       Car objCar;

       size = sizeof(objCar);

       printf("%s %d /r", "Class Car Size:", size);

}

輸出結果:Class Car Size:12

在類中又插入了一個字符型變量,結果Class Size變成了12。這個就是編譯器額外添加3個字符變量,做數據對齊處理,為了是提高CPU的計算速度。編譯器額外添加的東西我們是無法看見的。這也符合了結論中的第二條:加上編譯器為了CPU計算,作出的數據對齊處理。

既然,我們這樣定義類成員數據編譯器會額外的增加空。那麼,我們何不在定義類的時候就考慮到數據對齊的問題,可以多定義出3個字符類型變量作為預留變量,既能滿足數據對齊的要求,也給自己的程序添加了一些可擴展的空間。

三、只有成員函數的Size

class Car

{

public:

       Car(){};

       ~Car(){};

public:

       void Fun(){};

};

 

void main()

{

       int size = 0;

       Car objCar;

       size = sizeof(objCar);

       printf("%s %d /r", "Class Car Size:", size);

}

輸出結果:Class Car Size:1

噢,這是怎麼回事兒呢?再做一個實驗看看。

class Car

{

public:

       Car(){};

       ~Car(){};

public:

       void Fun(){};

private:

       int nLength;

       int nWidth;

};

void main()

{

       int size = 0;

       Car objCar;

       size = sizeof(objCar);

       printf("%s %d /r", "Class Car Size:", size);

}

輸出結果:Class Car Size:8

這次應該很清楚的了。函數是不占用類空間的。第一個例子中的Size為1個字節,正是編譯器為類創建一個隱含的一個字節的空間

class Car

{

public:

       Car(){};

       virtual ~Car(){};

public:

       void Fun(){};

};

 

void main()

{

       int size = 0;

       Car objCar;

       size = sizeof(objCar);

       printf("%s %d /r", "Class Car Size:", size);

}

輸出結果:Class Car Size:4

這次,讓析構函數為虛函數,看到了Class Size為4。這正是指向Virtual Table的指針vptr的Size。這正好符合了,結論中的第三條:加上為了支持虛函數,產生的額外負擔。

到此為止,一個Class Object究竟占用多少內存空間,已經完全說清楚了。但是,這只是針對單獨類,或者說是基類適用。對於子類,卻不一樣了。有興趣的朋友可以做一些實驗。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved