深度探索C++对象模型——关于对象
引言
以前讀《C++ Primer》的時候一直有一種感覺:該書雖然是C++入門書籍,初學者讀之卻覺晦澀,越往后讀越是如此。等到稍加理解后再讀該書,頓感醍醐灌頂,茅塞頓開。究其原因,在于原作者Stanley Lippman總是會有意無意地從編譯器的角度來介紹語言的細節(jié):對新手而言,哪里會去關注這樣底層的實現(xiàn)呢?
當讀到《Inside The C++ Object Model》時,上述感覺愈發(fā)強烈,兩書之間漸進講述的細節(jié)讓人讀后大呼過癮,也深感大師級作者筆觸間的睿智。
眾所周知,C++是一門支持多范式的語言(《Effective C++》Item1),其中最為重要,對C語言最大的變革便是面向?qū)ο蟮脑O計思想。而本書,依其簡介,探索“對象導向程序所支持的C++對象模型”下的程序行為。對于“對象導向性質(zhì)之基礎實現(xiàn)技術”以及“各種性質(zhì)背后的隱含利益交換”提供一個清楚的認識。檢驗由程序變形所帶來的效率沖擊。提供對象導向觀念和底層對象模型之間的效率測量。
關于對象
從C語言轉化到C++時,一個顯而易見的區(qū)別在于從全局數(shù)據(jù)過渡到數(shù)據(jù)封裝,那么其布局成本(Layout Costs)如何?答案是并未增加。本文后續(xù)將講述C++在布局以及存取時間上主要的額外負擔是由virtual引起,包括:
- virtual function 機制,用來支持有效率的“執(zhí)行期綁定”。
- virtual base class 虛基類機制,以實現(xiàn)共享虛基類的 subobject。
此外還有一些多重繼承的額外負擔,除此,C++毫無理由比C慢。
C++對象模式
類的成員包括類數(shù)據(jù)成員(靜態(tài)和非靜態(tài))和類成員函數(shù)(靜態(tài),非靜態(tài)和虛函數(shù))。
考慮如下簡單對象模型:
我們看到,成員本身并不在對象里,只有指向?qū)ο蟮闹羔槻旁?#xff0c;如此可以避免成員因類型不同而導致存儲空間不同。顯然,成員以每個slot的索引值來尋址。
考慮表格驅(qū)動對象模型(見上中圖1.2):
該方案中,把所有成員分離放在數(shù)據(jù)成員表和成員函數(shù)表兩個表中。類對象則含有指向這兩個表的指針。
遺憾的是,以上兩種方案都沒有真正應用于C++編譯器中,但它們的設計思想,或多或少被有所繼承。
來看C++對象模型的實現(xiàn)(見上右圖1.3):
在該模型中,非靜態(tài)數(shù)據(jù)成員放在類對象中,靜態(tài)數(shù)據(jù)成員則放在類對象外;靜態(tài)和非靜態(tài)函數(shù)成員也放在類對象外;虛函數(shù)以下步驟支持:
- 用一個虛函數(shù)表(VTBL)記錄指向虛函數(shù)的指針;
- 類對象則以一個指針(VPTR)指向虛函數(shù)表,vptr操縱由類的復制控制完成。
- 類所關聯(lián)的type_info object由虛函數(shù)表指出,位于第一個slot處。
該模型的優(yōu)點在于空間和存取時間的效率,主要缺點在于非靜態(tài)數(shù)據(jù)成員修改時必須重新編譯。
加上繼承
在虛擬繼承的情況下,基類不管被派生多少次,都只有一個實體(subobject)。C++最初的繼承模型不運用任何間接性:基類實體的數(shù)據(jù)成員被直接放在派生類對象中。后來又引入虛基類,則通過一些間接的基類表現(xiàn)方法。具體實現(xiàn)本文不做闡述,留待后續(xù)博文。
對象的差異
C++程序設計模型直接支持三種程序設計典范:
1.程序模型:即來自C語言的部分;
2.抽象數(shù)據(jù)類型模型:即封裝與抽象;
3.面向?qū)ο竽P?#xff1a;定義基類并派生出子類。
記住,純粹以一種典范寫程序,有利于整體行為的良好穩(wěn)固。
多態(tài)
C++以下列方法支持多態(tài):
1.隱含的轉化操作:把派生類的引用/指針轉化為基類的引用/指針;
2.虛函數(shù)機制:動態(tài)綁定;
3.dynamic_cast和typeid運算符。
那么,需要多少內(nèi)存才能表現(xiàn)一個類對象呢?
- 其非靜態(tài)數(shù)據(jù)成員的總和大小;
- 加上由譯注的需求而填補上去的空間;
- 加上為了支持virtual而產(chǎn)生的負擔(例如:指向虛函數(shù)表的指針的大小)。
?
?
轉載于:https://www.cnblogs.com/huashu/p/4339690.html
總結
以上是生活随笔為你收集整理的深度探索C++对象模型——关于对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java Web编程的主要组件技术——H
- 下一篇: C++#define的用法(含特殊)