c 基礎之空類的大小

2021-10-11 21:36:29 字數 1968 閱讀 4135

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

首先:我們要知道什麼是類的例項化,所謂類的例項化就是在記憶體中分配一塊位址

那我們先看看乙個例子:

#include

using namespace std;

class a

;class b

;class c :public a

;class d :public b, public c

;int

main()

結果:

為什麼會出現這種結果呢?初學者肯定會很煩惱是嗎?

類a,b明明是空類,它的大小應該為為0,為什麼 編譯器輸出的結果為1呢?

這就是我們剛才所說的例項化的原因(空類同樣可以被例項化),每個例項在記憶體中都有乙個獨一無二的位址,為了達到這個目的,編譯器往往會給乙個空類隱含的加乙個位元組,這樣空類在例項化後在記憶體得到了獨一無二的位址.所以a,b的大小為1

《深入理解c++物件模型》這本書是這樣解釋的:乙個空類事實上並不是空的,它有乙個隱晦的 1byte ,那是被編譯器安插進去的乙個char。這使得這個 class 的兩個不同的物件得以在記憶體中配置獨一無二的位址。

簡而言之乙個類的例項化物件有著它自己的獨一無二的位址,而位址是代表著一段記憶體大小,假如乙個空類的空間大小也為0,則我們不能為它分配記憶體,不能得到它的位址,因此編譯器會為空類新增乙個隱晦的char用以來標識空類的例項化物件。

而類c是由類a派生而來,它裡面有乙個純虛函式,由於有虛函式的原因,有乙個指向虛函式的指標(vptr),在32位的系統分配給指標的大小為4個位元組,所以最後得到c類的大小為4.

類d的大小更讓初學者疑惑吧,類d是由類b,c派生邇來的,它的大小應該為二者之和5,為什麼卻是8  呢?這是因為為了提高例項在記憶體中的訪問效率.類的大小往往被調整到系統的整數倍.並採取就近的法則,裡哪個最近的倍數,就是該類的大小,所以類d的大小為8個位元組.

在看個例子:

#include

#include

using namespace std;

class a

;class b

;int b:

:m_data3 =0;

void

main()

為什麼類b多了乙個資料成員,卻大小和類a的大小相同呢?因為:類b的靜態資料成員被編譯器放在程式的乙個global data members中,它是類的乙個資料成員.但是它不影響類的大小,不管這個類實際產生 了多少例項,還是派生了多少新的類,靜態成員資料在類中永遠只有乙個實體存在,而類的非靜態資料成員只有被例項化的時候,他們才存在.但是類的靜態資料成員一旦被宣告,無論類是否被例項化,它都已存在.可以這麼說,類的靜態資料成員是一種特殊的全域性變數.

所以a,b的大小相同.

接下來看看建構函式、析構函式、普通函式:

#include

using namespace std;

class a

voidf(

int x)~a

()private:

int x;

int g;};

void

main()

結果:

它們的結果均相同,可以看出類的大小與它當中的建構函式,析構函式,以及其他的成員函式無關,只與它當中的成員資料有關.

C 空類大小

class a class b class c public a class d public b,public c 類a,b明明是空類,它的大小應該為為 為什麼 編譯器輸出的結果為 呢?這就是我們剛才所說的例項化的原因 空類同樣可以被例項化 每個例項在記憶體中都有乙個獨一無二的位址,為了達到這個目...

c 空類的大小

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

c 空類的大小

定義乙個空類,沒有資料 class empty class test2 private empty private繼承 class test3 public empty public繼承 int tmain int argc,tchar argv cout class test1 class tes...