先看一個例子
#include<iostream>
using namespace std;
class a {};
class b{};
class e{
public:
void func1();
virtual void func2();
private:
static int n;
int m;
};
class c:public a{
virtual void fun()=0;
};
class d:public b,public c{};
int main(){
cout<<"sizeof(a)"<<sizeof(a)<<endl;
cout<<"sizeof(b)"<<sizeof(b)<<endl;
cout<<"sizeof(c)"<<sizeof(c)<<endl;
cout<<"sizeof(d)"<<sizeof(d)<<endl;
cout<<"sizeof(e)"<<sizeof(e)<<endl;
return 0;
}
輸出結果:
為什么會出現這種結果呢?首先要出需要多少內存表現一個類說起:一般而言有以下三種
1、非靜態數據成員的總和大小;
2、為了支持virtual而由內部產生的額外負擔,一般類內部產生指向虛函數的指針,32位的計算機每個指針占4個字節;
3、加上任何由於譯注的需求而填補上去的空間;
類a,b明明是空類,它的大小應該為為0,為什么 編譯器輸出的結果為1呢?這就是我們剛才所說的實例化的原因(空類同樣可以被實例化),每個實例在內存中都有一個獨一無二的地址,為了達到這個目的,編譯器往往會給一個空類隱含的加一個字節,這樣空類在實例化后在內存得到了獨一無二的地址.所以a,b的大小為1.
而類c是由類a派生而來,它里面有一個純虛函數,由於有虛函數的原因,有一個指向虛函數的指針(vptr),在32位的系統分配給指針的大小為4個字節,所以最后得到c類的大小為4.
類d的大小更讓初學者疑惑吧,類d是由類b,c派生邇來的,它的大小應該為二者之和5,為什么卻是8 呢?這是因為為了提高實例在內存中的存取效率.類的大小往往被調整到系統的整數倍.並采取就近的法則,里哪個最近的倍數,就是該類的大小,所以類d的大小為8個字節.
當然在不同的編譯器上得到的結果可能不同,但是這個實驗告訴我們初學者,不管類是否為空類,均可被實例化(空類也可被實例化),每個被實例都有一個獨一無二的地址.