1)C++對象大小計算,對象
C++對象的大小不同的編譯器的實現是不一樣的,以下僅討論.net2003,其他編譯的可能出現的結果以下也做了分析和猜測。在反推不同編譯器實現的C++對象的大小時。對齊是一個很重要也容易被遺忘的問題。
- class A{};
類A是一個空類,但是它的大小並不為0,編譯期間編譯器會插入一個char在其中,這個char我們是看不到的,這樣的用處是保證生成的不同對象具有不同地址,就是要對象裡有東西。
- class B:public virtual A{};
B類是對A類的虛繼承,B中一般會有指向A的實例的指針,在IA-32下為4bytes。這裡不同編譯器的實現差別很大,有的編譯器在B的對象中也 會保留A類的那個隱含的char,於是就有1+4=5個bytes,再考慮對齊,有些編譯器產生的結果為8bytes,但是在.net2003中優化過了,不會有A中的char,也就不需要對齊,只有4bytes大
- class C:public virtual A{};//同上
- class D:public B,public C{};
//D為8,如果編譯器不優化A中的char就會有1(A)+8(B)+8(C)-4(B對A虛繼承)-4(C對A虛繼承)+3(對齊)=12bytes
- class E{
int i;
};//很明顯4bytes
- class F{
double d;
};//很明顯8bytes
- class G{
double num;
char in;
};//8bytes對齊,所以是8(double)+4(int)+4(對齊)=16
- class H{
int num;
double in;
};//同上
- class I{
int num;
double in;
public:
virtual ~I(){};
};//8(double)+4(int)+4(對齊)+4(vptr)+4(對齊)=24
- class J{
double num;
int in;
public:
virtual ~J(){};
};//同上8(double)+4(int)+4(對齊)+4(vptr)+4(對齊)=24
- class K{
int i;
int k;
public:
virtual ~K(){};
};//4(int)+4(int)+4(vptr)=12
- class L{
int i;
int j;
L(){};
public:
float ll(int i) {
return 0.0;
}
- static int hhh(int i) {
return 0.0;
}
virtual ~L(){};
virtual ji(){};
};
//虛函數表的指針vptr,只有類中出現虛函數才會出現,它指向虛函數表,所有虛函數的地址存放在此表中。
//4(int)+4(int)+4(vptr)=12從中看出,不管有多少虛函數,大小不變,因為類中之保存虛函數表。
//不管成員函數有多少,類大小也不變,因為他們不保存在對象中,無論是否是靜態
int main(){
cout <<"A "<<sizeof(A)<<endl;
cout <<"B "<<sizeof(B)<<endl;
cout <<"C "<<sizeof(C)<<endl;
cout <<"D "<<sizeof(D)<<endl;
cout <<"E "<<sizeof(E)<<endl;
cout <<"F "<<sizeof(F)<<endl;
cout <<"G "<<sizeof(G)<<endl;
cout <<"H "<<sizeof(H)<<endl;
cout <<"I "<<sizeof(I)<<endl;
cout <<"J "<<sizeof(J)<<endl;
cout <<"K "<<sizeof(K)<<endl;
cout <<"L "<<sizeof(L)<<endl;
}
/*******************************************************************/
output .net2003
A 1
B 4
C 4
D 8
E 4
F 8
G 16
H 16
I 24
J 24
K 12
L 12