掀起你的蓋頭來——談VC++物件模型
一個C++程式設計師,想要進一步提升技術水平的話,應該多瞭解一些語言的語意細節。對於使用VC++的程式設計師來說,還應該瞭解一些VC++對於C++的詮釋。Inside the C++ Object Model雖然是一本好書,然而,書的篇幅多一些,又和具體的VC++關係小一些。因此,從篇幅和內容來看,譯者認為本文是深入理解C++物件模型比較好的一個出發點。
這篇文章以前看到時就覺得很好,舊文重讀,感覺理解得更多一些了,於是產生了翻譯出來,與大家共享的想法。雖然文章不長,但時間有限,又若干次在翻譯時打盹睡著,拖拖拉拉用了小一個月。
一方面因本人水平所限,另一方面因翻譯時經常打盹,錯誤之處恐怕不少,歡迎大家批評指正。
1 前言
瞭解你所使用的程式語言究竟是如何實現的,對於C++程式設計師可能特別有意義。首先,它可以去除我們對於所使用語言的神祕感,使我們不至於對於編譯器乾的活感到完全不可思議;尤其重要的是,它使我們在Debug和使用語言高階特性的時候,有更多的把握。當需要提高程式碼效率的時候,這些知識也能夠很好地幫助我們。
本文著重回答這樣一些問題:
* 類如何佈局?
* 成員變數如何訪問?
* 成員函式如何訪問?
* 所謂的“調整塊”(adjuster thunk)是怎麼回事?
* 使用如下機制時,開銷如何:
* 單繼承、多重繼承、虛繼承
* 虛擬函式呼叫
* 強制轉換到基類,或者強制轉換到虛基類
* 異常處理
首先,我們順次考察C相容的結構(struct)的佈局,單繼承,多重繼承,以及虛繼承;
接著,我們講成員變數和成員函式的訪問,當然,這裡麵包含虛擬函式的情況;
再接下來,我們考察建構函式,解構函式,以及特殊的賦值操作符成員函式是如何工作的,陣列是如何動態構造和銷燬的;
最後,簡單地介紹對異常處理的支援。
對每個語言特性,我們將簡要介紹該特性背後的動機,該特性自身的語意(當然,本文決不是“C++入門”,大家對此要有充分認識),以及該特性在微軟的VC++中是如何實現的。這裡要注意區分抽象的C++語言語意與其特定實現。微軟之外的其他C++廠商可能提供一個完全不同的實現,我們偶爾也會將VC++的實現與其他實現進行比較。
2 類佈局
本節討論不同的繼承方式造成的不同記憶體佈局。
2.1 C結構(struct)
由於C++基於C,所以C++也“基本上”相容C。特別地,C++規範在“結構”上使用了和C相同的,簡單的記憶體佈局原則:成員變數按其被宣告的順序排列,按具體實現所規定的對齊原則在記憶體地址上對齊。所有的C/C++廠商都保證他們的C/C++編譯器對於有效的C結構採用完全相同的佈局。這裡,A是一個簡單的C結構,其成員佈局和對齊方式都一目瞭然。
struct A {
char c;
int i;
};
譯者注:從上圖可見,A在記憶體中佔有8個位元組,按照宣告成員的順序,前4個位元組包含一個字元(實際佔用1個位元組,3個位元組空著,補對齊),後4個位元組包含一個整數。A的指標就指向字元開始位元組處。
2.2 有C++特徵的C結構
當然了,C++不是複雜的C,C++本質上是物件導向的語言:包含繼承、封裝,以及多型。原始的C結構經過改造,成了物件導向世界的基石——類。除了成員變數外,C++類還可以封裝成員函式和其他東西。然而,有趣的是,除非為了實現虛擬函式和虛繼承引入的隱藏成員變數外,C++類例項的大小完全取決於一個類及其基類的成員變數!成員函式基本上不影響類例項的大小。
這裡提供的B是一個C結構,然而,該結構有一些C++特徵:控制成員可見性的“public/protected/private”關鍵字、成員函式、靜態成員,以及巢狀的型別宣告。雖然看著琳琅滿目,實際上只有成員變數才佔用類例項的空間。要注意的是,C++標準委員會不限制由“public/protected/private”關鍵字分開的各段在實現時的先後順序,因此,不同的編譯器實現的記憶體佈局可能並不相同。(在VC++中,成員變數總是按照宣告時的順序排列)。
這篇文章以前看到時就覺得很好,舊文重讀,感覺理解得更多一些了,於是產生了翻譯出來,與大家共享的想法。雖然文章不長,但時間有限,又若干次在翻譯時打盹睡著,拖拖拉拉用了小一個月。
一方面因本人水平所限,另一方面因翻譯時經常打盹,錯誤之處恐怕不少,歡迎大家批評指正。
1 前言
瞭解你所使用的程式語言究竟是如何實現的,對於C++程式設計師可能特別有意義。首先,它可以去除我們對於所使用語言的神祕感,使我們不至於對於編譯器乾的活感到完全不可思議;尤其重要的是,它使我們在Debug和使用語言高階特性的時候,有更多的把握。當需要提高程式碼效率的時候,這些知識也能夠很好地幫助我們。
本文著重回答這樣一些問題:
* 類如何佈局?
* 成員變數如何訪問?
* 成員函式如何訪問?
* 所謂的“調整塊”(adjuster thunk)是怎麼回事?
* 使用如下機制時,開銷如何:
* 單繼承、多重繼承、虛繼承
* 虛擬函式呼叫
* 強制轉換到基類,或者強制轉換到虛基類
* 異常處理
首先,我們順次考察C相容的結構(struct)的佈局,單繼承,多重繼承,以及虛繼承;
接著,我們講成員變數和成員函式的訪問,當然,這裡麵包含虛擬函式的情況;
再接下來,我們考察建構函式,解構函式,以及特殊的賦值操作符成員函式是如何工作的,陣列是如何動態構造和銷燬的;
最後,簡單地介紹對異常處理的支援。
對每個語言特性,我們將簡要介紹該特性背後的動機,該特性自身的語意(當然,本文決不是“C++入門”,大家對此要有充分認識),以及該特性在微軟的VC++中是如何實現的。這裡要注意區分抽象的C++語言語意與其特定實現。微軟之外的其他C++廠商可能提供一個完全不同的實現,我們偶爾也會將VC++的實現與其他實現進行比較。
2 類佈局
本節討論不同的繼承方式造成的不同記憶體佈局。
2.1 C結構(struct)
由於C++基於C,所以C++也“基本上”相容C。特別地,C++規範在“結構”上使用了和C相同的,簡單的記憶體佈局原則:成員變數按其被宣告的順序排列,按具體實現所規定的對齊原則在記憶體地址上對齊。所有的C/C++廠商都保證他們的C/C++編譯器對於有效的C結構採用完全相同的佈局。這裡,A是一個簡單的C結構,其成員佈局和對齊方式都一目瞭然。
struct A {
char c;
int i;
};
譯者注:從上圖可見,A在記憶體中佔有8個位元組,按照宣告成員的順序,前4個位元組包含一個字元(實際佔用1個位元組,3個位元組空著,補對齊),後4個位元組包含一個整數。A的指標就指向字元開始位元組處。
2.2 有C++特徵的C結構
當然了,C++不是複雜的C,C++本質上是物件導向的語言:包含繼承、封裝,以及多型。原始的C結構經過改造,成了物件導向世界的基石——類。除了成員變數外,C++類還可以封裝成員函式和其他東西。然而,有趣的是,除非為了實現虛擬函式和虛繼承引入的隱藏成員變數外,C++類例項的大小完全取決於一個類及其基類的成員變數!成員函式基本上不影響類例項的大小。
這裡提供的B是一個C結構,然而,該結構有一些C++特徵:控制成員可見性的“public/protected/private”關鍵字、成員函式、靜態成員,以及巢狀的型別宣告。雖然看著琳琅滿目,實際上只有成員變數才佔用類例項的空間。要注意的是,C++標準委員會不限制由“public/protected/private”關鍵字分開的各段在實現時的先後順序,因此,不同的編譯器實現的記憶體佈局可能並不相同。(在VC++中,成員變數總是按照宣告時的順序排列)。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-620622/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 掀起C++0x的蓋頭來:C++之父Bjarne Stroustrup訪談C++JAR
- 敏捷開發系列之旅 第一站(掀起你的蓋頭來)敏捷
- Firefox 你的風頭能蓋過IE嗎?(轉)Firefox
- 面試——談談你對Java 物件導向思想的理解面試Java物件
- 大模型綜述來了!一文帶你理清全球AI巨頭的大模型進化史大模型AI
- 談談Spring中的物件跟Bean,你知道Spring怎麼建立物件的嗎?Spring物件Bean
- 語法:Python中的可覆蓋物件與不可覆蓋物件Python物件
- 如果你的頭圖載入不出來
- 科技巨頭們正在掀起AI收購戰AI
- C++——談談你對物件導向程式設計的認識C++物件程式設計
- 關於JavaScript物件,你所不知道的事(一)- 先談物件JavaScript物件
- Alink漫談(四) : 模型的來龍去脈模型
- 再談Delphi vs VC++(非常精彩) (轉)C++
- 談談JavaScript 的Navigator 物件JavaScript物件
- 談談java的類與物件Java物件
- 【蓋樓貼】評論中說說你心中的頭號程式設計師大神程式設計師
- 用歸納偏置來增強你的模型效能模型
- 再談在VB中呼叫VC++開發的DLL (轉)C++
- 談談 JAVA 的物件序列化Java物件
- Vue中eventbus很頭疼?我來幫你Vue
- “井蓋吃人”的屢見不鮮,智慧井蓋來了!
- 掀起一股中國風,最強中文AI作畫大模型文心ERNIE-ViLG 2.0來了AI大模型
- 談談我對物件導向以及類與物件的理解物件
- 淺談JVM記憶體結構 和 Java記憶體模型 和 Java物件模型JVM記憶體Java模型物件
- javascript原型物件的屬性不能夠覆蓋物件自有屬性JavaScript原型物件
- 網際網路掀起農家樂,巨頭上演AI掘金戰AI
- 談談Objective-C的物件拷貝Object物件
- 談談機器學習模型的可解釋性機器學習模型
- 談談GPT-4模型的亮點GPT模型
- 談談你對Promise的理解Promise
- 談談JVM(基礎模型)JVM模型
- NLP(十五)讓模型來告訴你文字中的時間模型
- c++中的物件模型C++物件模型
- 掀起的“元宇宙”熱潮,能給我們帶來什麼?元宇宙
- 非知名獵頭Henry 和你談-高薪是怎麼跳出來的?(轉自 IT PUB)高薪
- 掀起 OPEN API 的面紗API
- 談談JavaScript中建立物件(Object)JavaScript物件Object
- DOM 模型(文件物件模型)重點模型物件