類的大小。。。

class X{};

class Y:public virtual X{};

class Z:public virtual X{};

class A:public Y,public Z{};

 

 

sizeof    X:1  Y:4 Z:4 A:8

 

類的實例化,所謂類的實例化就是在內存中分配一塊地址,每個實例在內存中都有獨一無二的地址。同樣空類也會被實例化,所以編譯器會給空類隱含的添加一個字節,這樣空類實例化之後就有了獨一無二的地址了。所以空類的sizeof爲1。

 

Y和Z的大小受到三個因素的影響:

1、語言本身所造成的額外負擔(overhead): 當語言支持virtual base classes時,就會導致一些額外負擔。在derived class中,這個額外負擔反映在某種形式的指針身上,它或者指向virtual base class subobject,或者指向一個相關表格:表格中存放的若不是virtual base class subobject的地址,就是其偏移量(offset, 這正是VC++的做法)。

2、編譯器對於特殊情況所提供的優化處理:Virtual base class X subobject的1 bytes大小也出現在Class Y和Z身上。某些編譯器會對empty virtual base class 提供特殊支持。

3、Alignment的限制:Class Y和 Z的大小截至目前爲5 bytes。在大部分機器上,羣聚的結構體大小會受到alignment的限制,使它們能夠更有效率地在內存中被存取。在32位機上,alignment是4bytes,所以class Y和Z必須填補3 bytes。最終得到的結果就是8 bytes。

現在有些編譯器提供“空基類優化”(empty base class optimization),一個empty virtual base class被視爲derived class object最開頭的一部分,也就是說它並沒有花費任何的額外空間。這就節省了上述第2點的1bytes,也就不再需要第三點所說的3bytes的填補。

 

 

 

class Onefunc{

public:

void go(void);

};

 

void Onefunc::go()

{

cout<<"HAHA"<<endl;

}

 

 

cout<<"Onefunc:"<<sizeof(Onefunc)<<endl; //結果:Onefunc:1

類的大小與(非虛)函數無關,其大小決定於:成員變量,vptr(指向VTable的virtual pointer), Vbptr(virtual base table pointer)。在類Onefunc裏什麼都沒有,故大小與空類大小相同。

 

【轉】 C++類的大小——sizeof()

 

先看這麼個問題——已知:

class CBase
{
    int  a;
    char *p;
};

那麼運行cout<<"sizeof(CBase)="<<sizeof(CBase)<<endl;之後輸出什麼?

這個應該很簡單,兩個成員變量所佔的大小有嘛——8。可由時候人就是愛犯這個錯誤:這麼簡單的問題人家會問你?再想想……好像C++類裏面有個什麼函數指針,也應該佔字節吧!?什麼指針來着?忘了(還是水平低不紮實)!流汗中……算了姑且認爲是構造函數和析構函數吧。一人一個加上剛纔那8個16個。好笑嗎?這是我犯的錯誤!!!到底C++類的sizeof是多少呢?沒有所謂的函數指針問題嗎?不甘心,編個例子看看:

第一步:給丫來個空的(不好意思上火粗魯了)

class CBase
{
};

運行cout<<"sizeof(CBase)="<<sizeof(CBase)<<endl;

sizeof(CBase)=1;

爲什麼空的什麼都沒有是1呢?查資料……查啊查……OK這裏了:先了解一個概念:類的實例化,所謂類的實例化就是在內存中分配一塊地址,每個實例在內存中都有獨一無二的地址。同樣空類也會被實例化(別拿豆包不當乾糧,空類也是類啊),所以編譯器會給空類隱含的添加一個字節,這樣空類實例化之後就有了獨一無二的地址了。所以空類的sizeof爲1。繼續下一步:

第二步:

還是最初的那個類,運行結果:sizeof(CBase)=8

沒什麼說的,兩個內部變量的大小。難道我記錯了沒有什麼指針問題的存在?再試試(早這麼有求知慾也不會丟人了,這回來勁了)

第三步:添個虛函數

class CBase
{
public:
    CBase(void);
    virtual ~CBase(void);
private:
    int   a;
    char *p;
};

再運行:sizeof(CBase)=12

嗨!問題出來了!!跟虛函數有關。爲什麼呢?查資料ing……

有了:“C++ 類中有虛函數的時候有一個指向虛函數的指針(vptr),在32位系統分配指針大小爲4字節”噢原來如此害死我了。那麼繼承類呢?

第四步:

基類就是上面的了不寫了

class CChild :
    public CBase
{
public:
    CChild(void);
    ~CChild(void);
private:
    int b;
};

運行:cout<<"sizeof(CChild)="<<sizeof(CChild)<<endl;

輸出:sizeof(CChild)=16;

可見子類的大小是本身成員變量的大小加上子類的大小。

有空再補一下關於虛函數指針的知識吧。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章