一直不明白c++中類中的函數和成員變量在實例化對象后在內存中究竟是個什么樣的布局。一度以為一個對象的內存布局應該包括函數體和成員變量,后來才知道對象的內存布局是不包括函數體的。也就是說實例化一個類后,該對象占用的內存空間大小實際上是它的成員變量在內存中所占用空間大小(注意,含有靜態成員變量和虛函數的類對象例外)。以下分析以下c++類對象在內存中的布局,并且探討在給定一個類的成員變量的類型和數量時,如何使得類實例化后對象所占用的內存空間最小(考慮變量在內存中對齊)。
先給出一個類,如下:
1 class A
2 {
3 public:
4 A()
5 {
6 cout << "A" << endl;
7 }
8 virtual ~A()
9 {
10 cout << "~A" << endl;
11 }
12 virtual void printA()
13 {
14 cout << "printA" << endl;
15 }
16 private:
17
18 int a;
19 char c;
20 char e;
21 double b;
22 static double d;
23 };
24
25 int main()
26 {
27
28 A a;
29 cout << sizeof(a) << endl; //輸出是24
30 return 0;
31 }
以上代碼輸出是:24。也就是說對象a占用內存空間大小是24字節,這個24字節是怎么得來的呢?我們注意到在類A中存在虛函數,而只有類中有虛函數存在,則可以知道,在每個類對象占用內存空間的首部都會有一個虛函數表,這個虛函數表可以看成是一個指針數組,在對象a中虛函數表中總共有2項,因為類A中存在兩個虛函數,每個虛函數都在虛函數表中有一個項對應。現在我們知道虛函數表是2個指針的內存大小,所以是2*4=8字節。然后a,c,e總共占用4+1+1=6字節,由于需要進行內存對齊,所以實際上它占用的大小是8字節(即類對象中的內存按照占用內存空間最大的變量來對齊,static變量不考慮在內)。然后是b占用8字節,static變量d不占用空間,綜上對象a占用空間大小為8(虛函數表)+8(a,c,e)+8(b)=24字節。具體可以在vs下調試,查看a的地址。
由于要考慮到內存對齊,所以。。今天有事,以后待續