《深度探索C++对象模型》--1 关于对象
1、封裝成本
與C比較,在virtual沒有參與的情況下,C++的封裝沒有增加成本。C++在布局以及存取時間上的主要而外負擔是由virtual引起的。包括:virtual function機制和virtual base class。
2、C++對象模式
在C++中,有兩種class data members:static和nonstatic,以及三種class member functions:static、nonstatic和virtual。
(1)簡單對象模型
一個object是一系列的slots,每一個slots指向一個members。
(2)表格驅動對象模型
將所有與members相關的信息抽出來,放在一個data member table和一個member function table中,class object內含指向這兩個表格的指針。
(3)C++對象模型
Nonstatic data members被配置于每一個class object之內,static data members被存放在個別的class object之外;static function members也被放在個別的class object之外。而virtual functions 則:
(a)每一個class 產生一堆指向virtual functions的指針,放在表格之中。這個表格稱為virtual table (vtbl)。
(b)每一個class object 被安插一個指針,指向相關的virtual table。這個指針稱為vptr。vptr的設定和重置都由每一個class的constructor、destructor和copy assignment運算符自動完成。每一個class 所關聯的type_info object也經由virtual table指出。
3、關鍵詞所帶來的差異
(1)struct與class
struct關鍵詞實現了C的數據抽象概念,class關鍵詞實現C++的ADT(abstract data type)觀念。struct和class關鍵詞不會造成什么差別,真正特性是由聲明(public、private、protected)本身決定的。
(2)C++中凡處于同一個accesssection的數據,必定保證以其聲明次序出現在內存布局中,然而被放置在多個accesssections中的各筆數據,排列次序就不一定了。這與C中按照聲明順序分配空間不同。
(3)如果迫切需要一個相當復雜的C++ class的某部分數據,使它擁有c聲明的那種樣子,那么那一部分最好抽取出來成為一個獨立的struct聲明。利用組合,而非繼承。
C struct在C++中的一個合理用途,是當你要傳遞”一個復雜的classobject 的全部或部分“到某個C函數中去時,struct的聲明可以將數據封裝起來,并保證擁有與C兼容的空間布局,然而這項保證只在組合的情況下才存在,如果是繼承而非組合,編譯器會決定是否應該有額外的datamembers 被安插到 basestruct subobject之中。
4、對象的差異
C++程序設計模型直接支持三種programming paradigms(程序設計范式)。
(1)程序模型(proceduralmodel)。
如C一樣的處理過程。
(2)抽象數據類型模型(abstract data type model,ADT)。
所謂抽象是和一組表達式一起提供的,那時其運算定義仍然隱而未明。如=、==。
(3)面向對象模型(object-orientedmodel)。
只有通過pointer或reference的間接處理,才支持OO程序設計所需的多態性質。
一個 pointer或一個reference之所以支持多態,是因為它們并不引發內存中任何“與類型有關的內存委托操作(type-dependentcommitment)”;會受到改變的只是它們所指向的內存的“大小和內容解釋方式”而已;當一個base classobject被直接初始化為(或是被指定為)一個derivedclass object時,derivedobject就會被切割,以塞入較小的base type內存中,多態于是不再呈現。
5、需要多少內存才能表現一個classobject?
(1)nonstatic data members的總和大小。
(2)加上任何由于alignment的需求而填補上去的空間(可能存在與members之間,也可能存在與集合體邊界)。
(3)加上為了支持virtual而由內部產生的任何額外負擔。
一個指針(或是一個reference,本質上一個reference通常是以一個指針來實現的),不管它指向哪種數據類型,指針本身所需的內存大小是固定的。(一個機器地址,即機器字長,如32位機器是4bytes)
6、需要理解的知識點:
(1)C++對象模型
有兩個概念可以解釋:(1)語言中直接支持面向對象程序設計的部分。(2)對于各種支持的底層實現機制。本書針對第二個概念。
(2)面向對象與基于對象的區別
面向對象的三大特點(封裝,繼承,多態)卻一不可,通常“基于對象”使用對象,但是無法利用現有的對象模板產生新的對象類型,繼而產生新的對象,也就是說“基于對象”沒有繼承的特點,而“多態”是表示為父類類型的子類對象實例,沒有了繼承的概念也就無從談論“多態”。現在的很多流行技術都是基于對象的,它們使用一些封裝好的對象,調用對象的方法,設置對象的屬性。但是它們無法讓程序員派生新對象類型。他們只能使用現有對象的方法和屬性。當判斷一個新的技術是否是面向對象的時候,通??梢允褂煤髢蓚€特性來加以判斷。“面向對象”和“基于對象”都實現了“封裝”的概念,但是面向對象實現了“繼承和多態”,而“基于對象”沒有實現這些。
(3)虛擬繼承
為了解決從不同途徑繼承來的同名的數據成員在內存中有不同的拷貝造成數據不一致問題,將共同基類設置為虛基類。這時從不同的路徑繼承過來的同名數據成員在內存中就只有一個拷貝,同一個函數名也只有一個映射。這樣不僅就解決了二義性問題,也節省了內存,避免了數據不一致的問題。
class 派生類名:virtual 繼承方式? 基類名
virtual是關鍵字,聲明該基類為派生類的虛基類。
在多繼承情況下,虛基類關鍵字的作用范圍和繼承方式關鍵字相同,只對緊跟其后的基類起作用。聲明了虛基類之后,虛基類在進一步派生過程中始終和派生類一起,維護同一個基類子對象的拷貝。
?
總結
以上是生活随笔為你收集整理的《深度探索C++对象模型》--1 关于对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Effective C++ -- 零散知
- 下一篇: 《深度探索C++对象模型》--2 构造函