《深度探索C++對象模型》讀書筆記之Data語意學

1、  Data member的佈局是怎樣的?

非靜態數據成員

1>    在同一個Access Section(也就是private,public,protected等區段)中,較晚出現的數據成員在classobject中有較高的地址。

2>    允許編譯器將同一類型的多個Acess Section的順序自由排列,而不必在乎它們的聲明次序(但似乎沒有編譯器這樣做)。

 靜態數據成員

1>    靜態數據成員存放在程序的data segment中,和個別的class object無關。

 

2、  Data member的存取會不會有額外的代價?

1>    靜態數據成員:static data members被編譯器提出於class之外,並被視爲一個global變量(但只在class生命範圍內可見)。每一個member的存取許可(privatepublicprotected),以及與class的關聯,並不會導致任何空間上或者執行時間上的額外負擔。

2>    非靜態數據成員:想要對一個nonstatic data member進行存取操作,編譯器需要把class object的起始地址加上data member的偏移量。每個nonstatic data member的偏移量在編譯時期即可獲知,甚至如果member屬於一個base classsubobject(多繼承)也是一樣。因此存取一個nonstatic data member,其效率和存取一個C struct member或者一個nonderived classmember是一樣的。

備註:如果存取操作涉及到虛繼承中的指針/引用存取則會導入一層間接性。因爲不知道指針指向的對象或者引用的對象的具體類型,所以存取操作需要延遲至執行期,經由一個額外的間接導引才能解決。

 

3、  Data member在繼承、擁有虛函數(即、多態)、虛繼承的情況下的佈局對subobject的數據成員的存取(或派生類對象轉型爲基類類型)的影響是怎樣的?

1>    單一繼承不包含虛函數:與普通的C結構體佈局一致,因此沒有任何額外的空間和存取負擔。

2>    單一繼承並含有虛函數:數據成員存取(轉型)無影響,當然虛函數的調用的負擔則不可避免(將虛函數表指針佈局在class首尾均是如此)。

3>    多繼承:不同於單一繼承,問題主要發生於derived class object和其第二或者後繼的base class objects之間的轉換。不論是直接轉換還是由其所支持的virtual function機制做轉換。由於members的位置在編譯時就確定了,所以存取members只需要一個簡單的offset運算(加上或減去介於中間的base class subobject)。

4>    虛基類的支持沒有具體的標準,但數據成員存取需要間接完成,有時間的負擔。一、按照MS的“virtual base class table的方法,需要在object中添加一個該表的指針,通過指針間接存取。二、如果按照“在virtual function table中放置offset”只需要計算offset完成數據成員存取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章