天天看點

inside the c++ object model 讀書筆記(第一章)

Chapter 1     Object Lessons C語言是面向過程的程式設計方法,由一堆基于算法而分割的任務來實作。而C++增加了資料和操作的封裝,是面向對象的程式設計方法 Layout Costs for Adding Encapsulation 基本上不會有什麼cost的增加。但是如果你使用了virtual,會有一些空間和時間消耗。如果用了多繼承,在子類和父類的轉換時會有一些overhead。一般來說,c++程式相對于c程式并不會大多少或者慢多少。 C++ 對象模型 在C++中,有兩種類的成員資料類型—static和非static.三種成員函數—static、非static和virtual. Ø A Simple Object Model 一個簡單的對象模型就是對于類中的所有成員—包括資料成員和函數,并不是直接放在對象中,而是用一個一個指針一一對應的指向它們。這樣子一個對象由一組指針序列組成。類的大小就是 (指針大小*成員數目).這樣的好處是避免了不同資料類型大小不一造成的空間申請問題。 Ø A Table-driven Object Model 由表驅動的對象模型将資料和操作分開。一個對象中包含兩個指針,一個指向資料成員表,另一個指向函數成員表。 Ø The C++ Object Model Stroustrup初始的C++ 對象模型來自于對簡單對象模型在空間和通路時間上的優化。非static資料直接在類對象中存儲;Static資料儲存在類對象之外。Static和非static函數成員儲存在類對象之外。 Virtual虛函數通過兩個步驟來支援: 1.       每個類生成一張包含指向虛函數的指針(s)的表,一般叫做虛函數表(vtable)。 2.       一個指向虛函數表的指針(vptr),将被插入到每個實際的類對象中。關于Vptr的操作由編譯器根據具體情況(後面章節會詳細講)自動完成。用于支援RTTI的type_info對象也放在vtable中,一般會放在第一個位置。 Adding inheritance C++支援單繼承也支援多繼承。另外,還支援虛繼承(virtual inheritance)。在虛繼承中,隻有一個基類的執行個體會被儲存,而不管這個類在繼承鍊中被繼承了多少次。 How the Object Model Effects Program 會隐藏很多東西在背後。是以才要看這本書。咔咔  A Keyword Distinction 讨論c和c++一些關鍵字的問題。主要是struct和class關鍵字的差別及原因。   An Object Distinction C++支援三種程式設計範例(paradigm) 1.       Procedural Model 2.       ADT(abstract data type) Model 3.       Object-oriented Model C++中支援多态的三種方法: 1.       通過一系列的隐形轉換。比如由子類的指針轉成基類指針: Shape *ps = new Circle(); 2.       通過虛函數機制 3.       通過dynamic_cast和typeid操作符 一個類對象在記憶體的大小由一下因素決定: Ø  非static資料成員的大小累加 Ø 對齊(alignment)機制所需要添加的空間 Ø 支援virtuals增加的空間 The Type of a Pointer 一個指針本身的大小是确定的,而不管它是指向什麼類型,一般就是機器指令位址的大小。指針類型的不同主要是在于其所指的對象的不同。指針的類型告訴編譯器如何解析其包含的位址的内容和要解析的内容的大小。 而對于void*型指針,它可以指向任何類型,其實就是包含一個位址值而已;但是你不能通過void*指針對對象進行操作。 是以通常情況下的cast并不會對實際包含的位址做改變(多重繼承可能造成改變)。它隻是改變了該位址對應記憶體要解析的大小和構成。 Adding Polymorphism 這部分要畫圖才講的清楚。基本上實作多态就是在基類裡插入一個vptr(如果有多繼承,情況會更複雜,後面章節會講)。這個vptr可以插入在最前面,也可以插入在末尾,其實也可以放在中間。标準裡并沒有規定vptr的位置。而VC是将其放在最前。 由于插入了vptr,包含虛函數的類對象大小會增加。一般是4bytes. 由于vptr是放在基類中,是以我們可以用一個基類的指針來調用子類的虛函數。因為對于具體對象的虛函數表中的函數來說,還是依具體對象的類型而定的。 而對于一個基類的對象來說,它的大小并不會改變。如果你用一個繼承類來初始化或者複制給基類。繼承類會被切割來适應基類的大小。而由于virtual的機制是根據實際的對象類型來決定的。這種情況下,該對象vptr指向的仍是基類的vtable.

繼續閱讀