c++物件模型的主要優點在於它空間和訪問時間的效率;主要缺點是,如果應用程式**本身並未改變,但所用的class object的nonstatic data members有所修改(可能是增加、移除或修改),那麼那些應用程式**同樣得重新編譯。關於這點,前面的的**驅動模型就提供了較大的彈性,因為它多提供了一層間接性,不過它也因此付出空間和執行效率兩方面的代價。
加上繼承 (adding inheritance)c++支援單一繼承:
class libarary_materials ;
class book : public library_materials ;
class rental_book : public book ;
c++也支援多重繼承:
class iostream:
public istream,
public ostream ;
甚至,繼承關係也可以指定為虛擬:
class istream : virtual public ios
class ostream : virtual public ios
在虛擬繼承的情況下,base class不管在繼承串鏈中被派生多少次,永遠只會存在乙個實體,例如iostream之中就只有virtual ios base class的乙個實體。
在乙個derived class如何在本質上模塑base class的實體呢?在"簡單物件模型"中,每乙個base class可以被derived class object內的乙個slot指出,該slot內含base class subobject的位址,這個體制的主要缺點是,因為間接性而導致空間和訪問時間上的額外負擔,優點則是class object的大小不會因其base classes的改變而受到影響。
另一種base table模型,這種模型的base class table被產生出來時,**中的每乙個slot內含乙個相關的base class位址,這很像virtual table內含每乙個virtual function的位址一樣,每乙個class object內含乙個bptr,它會被初始化,指向其base class table.這種策略的主要缺點是由於間接性而導致的空間和訪問時間上的額外負擔,優點則是在每乙個class object中對於繼承都有一致的表現方式:每乙個class object都應該在某個固定位置上安放乙個base table指標,與base classes的大小或數目無關。第二個優點是,不需要改變class objects本身,就可以放大、縮小、或更改base class table.
不管上述哪一種體制,"間接性"的級數都將因為繼承的深度而增加,例如乙個rental_book需要兩次間接訪問才能夠探取到繼承自library_materials的members,而book只需要一次。如果在derived class內複製乙個指標,指向繼承串鏈中的每乙個base class,倒是可以獲得乙個永遠不變的訪問時間。當然這必須付出代價,因為需要額外的空間來放置額外的指標。
c++最初採用的繼承模型並不運用任何間接性:base class subobject的data members被直接放置於derived class object中,這提供了對base class members最緊湊而且最有效率的訪問。缺點是base clas members的任何改變,包括增減、移除或改變型別,都使得所有用到此base class或者其derived class的objects必須重新編譯。
自c++2.0起才新匯入的virtual base class,需要一些間接的base class表現方法。virtual base class的原始模型是在class object中為乙個有關聯的virtual base class加上乙個指標,其他演化出來的模型則若不是匯入乙個virtual base class table,就是擴充原已存在的virtual table,以便維護每乙個virtual base class的位置。
物件模型如何影響程式 (how the object model effects programs) 這對程式帶來什麼意義呢?不同的物件模型會導致"現有的程式**必須修改"以及"必須加入新的程式**"兩個結果。例如下面的這個函式,其中class x定義了乙個copy constructor,乙個virtual destructor和乙個virtual function foo:
x foobar()
這個函式有可能在內部被轉化為:
// 可能的內部轉換結果
// 虛擬c++碼
void foobar(x &_result)
// 不需使用named return statement
// 不需要銷毀local object xx
return;
}
沒有建立臨時變數物件,也不需要銷毀臨時物件。 C 物件模型 關於物件 第一章筆記
讀完c 物件模型書後,做乙個筆記整理 第一章 關於物件 第二章 建構函式語義學 第三章 data語義學 第四章 function語義學 第五章 構造拷貝解析語義學 第六章 執行期語義學 第七章 在物件模型的尖端 c 增加封裝後並未增加物件布局開銷,基布局及訪問時間額外負擔是由virtual引起 c ...
《深度探索C 物件模型》第一章 關於物件
在class中,乙個non inline member function只會誕生乙個函式實體,而inline function會在每乙個使用者 模組 身上產生乙個函式實體。個人理解 inline函式在每乙個使用了這個函式的地方都會進行 替換,所以會產生多個函式實體,而成員函式只會有乙個實體,並且多個...
《深入探索C 物件模型》第一章 關於物件
1 封裝後的成本會增加嗎?對於乙個普通的class,即不含虛函式,沒有繼承virtual base class 雖然通常不含有虛函式說明不存在繼承體系 封裝後,並沒有增加成本,data members直接放在object內,就像在struct裡的表現一樣,而member functions雖然在cl...