C 類記憶體結構分析

2021-05-26 07:37:49 字數 1601 閱讀 8372

本文的目標是闡述清楚

c++的類相關的記憶體結構問題。

這個問題對於已經很了解的人來說,太簡單了,這還有必要拿出來與人分享嗎?但對於那些不了解的人,始終有一層窗戶紙不能被捅破,似乎總是不能非常到位的理解本質。

本文的闡述過程會分為幾個階段,類與物件的關係,物件到底是什麼,類的函式時如何被處理的,多型是如何被處理的,其中最核心的是對類函式的實質的理解。1、

類與物件的關係。

我們該如何理解類與物件的關係?那需要先了解什麼是類,類是乙個抽象的定義,包含了一組資料,一組對資料的操作。那麼類與物件的關係,就類似於

int與整形變數的關係,類僅僅定義了一種特殊的型別,它沒有位址,所以程式中葉沒有任何地方去儲存乙個類,而物件是乙個類的例項化,是真實存在於記憶體中的,所以物件是有位址的。 2

、物件到底是什麼?

既然上乙個問題提到了,物件是類的一種存在形式,是真實存在於記憶體中的,那麼它到底是什麼樣子?如果大家檢視下某個類物件的記憶體資訊,會清楚的發現,物件的位址上順序的存放著該物件內變數的值。這樣說來,物件只是乙個位址,該位址記錄了乙個資料塊,而就是這個資料塊代表了物件的存在。3、

類的函式如何被編譯器處理?

我們要問自己乙個問題,函式到底是什麼?大家都知道,但請大家一定要深化這個概念,函式只是一片記憶體,一片記錄了函式執行**執行的記憶體,那麼這樣的話,函式指標也就很容易理解了,就是函式對應的記憶體的入口位址而已(對於想深入理解函式引數傳遞的朋友可以參見其它文章)。

類函式與

c函式有何不同?類函式是屬於某個類的,而

c函式可以被任意呼叫,但事實真的是這樣嗎?類函式只能被該類呼叫嗎?下面的**證明不是該類的函式也是可以呼叫的。

***那麼如何解釋上邊的**?

a類中的函式為何也可以被

b呼叫?這只有乙個解釋,那就是類在編譯的時候,函式是全域性的,類似於

c函式。這樣就可以完整的來看乙個類物件在記憶體中的分布了,首先是一塊資料區,儲存了物件變數資料,其次是多個類函式對應的記憶體區,並且函式對應的記憶體不會因為建立另乙個物件而發生變化。

這樣,本質上來說,只要符號類函式的呼叫形式,任何乙個物件都可以呼叫任何乙個類函式,這樣的手段可能在建立類處理對映上很有用吧。4、

多型是如何被處理的?

什麼是多型?多型就是不同的類來說,可以有同乙個函式定義的實現,並在具體呼叫時,能夠根據類的型別找出該類對應的函式定義。

一般來說,對於

pa->f1();

這樣的呼叫來說,函式呼叫的位址是在編譯的時候確定了的(雖然位址那個時候是相對的),而如果

f1是乙個虛函式,具體真實的函式位址還不能獲取到,這時該如何處理?

對於這個問題,大家可以先考慮考慮。

對於這個問題,我的想法就是在物件

pa中記錄下所有虛函式的相對位址,如果當前類沒有實現,那麼就記錄基類的虛函式位址,確保每個虛函式都有對應的函式位址,在具體編譯這樣的語句時,就可以先檢測是否為虛函式,如果是,則通過物件內讀取的真實的虛函式位址來進行處理,事實上,通過除錯發現

c++編譯器也確實是這麼做的,例如

vc中,是將變數的第乙個指標記錄了該類對應的虛函式陣列,該陣列記錄了每個虛函式對應的位址。

因為我對問題的理解與大家對問題的理解角度不一樣,或關注的重點不一樣,如果大家有不清楚的地方,可以提出來,我會將我的努力與大家分享。

c 類記憶體結構

當乙個c 類被例項化的時候,從記憶體當中會產生一塊關於該類的記憶體區域。那麼,乙個類對應的記憶體是怎麼樣的呢?類裡面有成員變數,有函式,還有虛函式等,具體自己去研究,我這裡只介紹一種方法,可以檢視乙個類的記憶體分布,好記性不如爛筆頭,幫自己記憶了。用vs系列工具的弟兄,我們以vs2008為例,用所有...

C 類的記憶體結構

摘自jerry19880126 沒有複寫的繼承 複寫的繼承 記憶體分布從父類到子類,依次如下 base中有乙個虛表指標 derivedclass1繼承了base,記憶體排布是先父類後子類。derivedclass2的情況是類似於derivedclass1的。derivedderivedclass,由...

C程式 程序記憶體結構分析

1.每個程序都執行在自己私有的記憶體空間中 即虛擬位址空間 在32位系統中,4gb的程序位址東健被分為使用者空間和核心空間兩個部分。使用者空間佔據著0 3gb 用16進製表示為0xc0000000 而核心空間的範圍是3gb 4gb。對於乙個程序而言,都會涉及3種不同的資料段,分別是 段 資料段和堆疊...