C 類的大小

2021-06-23 09:27:13 字數 3130 閱讀 4674

乙個空類class a{};的大小為什麼是1,因為如果不是1,當定義這個類的物件陣列時候a objects[5]; objects[0]和objects[1]就在同乙個位址處,就無法區分。

單繼承

#includeusing

namespace

std;

class

aprivate

:

char k[3

];};

class b: publica};

intmain()

vs和gcc下

執行結果:a's size is 8

b's size is 8

說明:有虛函式的類有個virtual table(虛函式表),裡面包含了類的所有虛函式,類中有個virtual table pointers,通常成為vptr指向這個virtual table,占用4個位元組的大小。成員類b public繼承於a,類b的虛函式表裡實際上有兩個虛函式a::aa()和b::bb(),類b的大小等於char k[3]的大小加上乙個指向虛函式表指標vptr的大小,考慮記憶體對齊為8。

#includeusing

namespace

std;

class

aprivate

:

char k[3

];};

class b: publica};

intmain()

vs和gcc下

執行結果:a's size is 8

b's size is 8

說明:類b看上去沒有虛函式,但實際上它有,只是沒有重寫,因為public繼承,所以有從a繼承過來的虛函式a::aa(),實際上類a和類b的虛函式表裡的函式都是a::aa()。

#includeusing

namespace

std;

class

a

virtual

void

aa2(){}

private

:

char k[3

];};

class b: public

a

virtual

void

bb2(){}

};int

main()

vs和gcc下

執行結果:a's size is 8

b's size is 8

說明:乙個類裡若有虛函式,無論有多少個虛函式都只有乙個指向虛表的指標,虛表中的每乙個表項儲存著乙個虛函式的入口位址。當呼叫虛函式時,先找到虛表中它對應的表項,找到入口位址再執行。對於直接單繼承,無論類b中有無虛函式,由於它繼承了類a,且類a裡含有虛函式,因此如果類b有虛函式,那麼它和類a的是在同乙個屬於類b的虛表裡,這張虛表的虛函式為a::aa()、a::aa2()、b::bb()、b::bb2()。注意:類a裡的私有成員在類b裡仍占有記憶體。

多繼承

#includeusing

namespace

std;

class

a

virtual

void

aa2(){}

private

:

char k[3

];};

class

b

virtual

void

bb2(){}

};class c: public a,public

b //

重寫了a的aa()

virtual

void

cc(){}

};int

main()

vs和gcc下

執行結果:a's size is 8

b's size is 4

b's size is 12

說明:類a和b的大小就不解釋了,參照上面。類c多重繼承於a和b(有虛函式覆蓋),那麼類c的大小是多少?先看成員變數,有乙個繼承a的char k[3]。再看虛函式,類c的中虛函式是怎麼分布的?先有乙個虛函式表,裡面有繼承於類a的虛函式和c自己的虛函式(c::aa(), a::aa2(), c::cc()),如果c沒有重寫aa(),那麼第乙個虛函式就是a::aa(),接著有第二張虛函式表是繼承包含類b的虛函式b::bb()、b::bb2()(類c沒有重寫b的虛函式)。總的大小就是2張虛表的大小(也即兩個虛函式指標的大小)8位元組加上3位元組的k[3],考慮記憶體對齊,就是12位元組。

虛繼承

#includeusing

namespace

std;

class

aprivate

:

char k[3

];};

class b: virtual

publica};

intmain()

vs和gcc下

執行結果:a's size is 8

b's size is 12

說明:類b裡包含,繼承的char k[3],繼承的虛函式,類b的虛函式表裡有a::aa(),因為是虛繼承,還有乙個指向父類的指標,該指標為指向虛基類的指標(pointer to virtual base class)。考慮記憶體對齊,總大小為12。

#includeusing

namespace

std;

class

aprivate

:

char k[3

];};

class b: public

virtuala};

intmain()

vs執行結果:a's size is 8

b's size is 16

gcc執行結果:a's size is 8

b's size is 12

說明:對於虛繼承,類b虛繼承類a時,首先要通過加入乙個指標來指向父類a,該指標被稱為虛基類指標。然後包含從父類繼承過來的3個char,再加上乙個虛函式指標。考慮記憶體對齊,在gcc下結果是4+4+4=12。在vs下,結果是16,why?這一題和上一題區別只是在類b中新增了乙個虛函式,但是兩個題目中類b都有虛函式表。在vs下除錯檢視彙編**,發現多出來的4位元組什麼也沒有。

c 類的大小

初學者在學習物件導向的程式語言時,或多或少的都些疑問,我們寫的 與最終生編譯成的 卻 大相徑庭,我們並不知道編譯器在後台做了什麼工作 這些都是由於我們僅停留在語言層的原因,所謂語言層就是教會我們一些基本的語法法則,但不會告訴我們為什麼這麼做?今天和大家談的一點感悟就是我在學習程式設計過程中的一點經驗...

C 類的大小

前言 c 類所占用的記憶體空間實際上是指類的例項所占用的記憶體空間。其大小是由類中的成員變數決定的 靜態成員變數除外 由於成員函式放到 區由類的各個例項共享,故成員函式對類占用記憶體大小沒有影響。具體地說,類占用記憶體大小由以下三個方面決定 1.非靜態成員變數的記憶體占用之和 2.考慮記憶體對其的問...

C 類的大小

注 以下測試,均是在 pragma pack 4 的情況下編譯的.1.首先,空類的大小並不是0,而是1 include using namespace std 記憶體對齊的方式是以4個位元組為一組.pragma pack 4 class a int main 2.int,float為4個位元組,do...