前言
對象模型是深層結構知識,關係到“與語言無關、與平臺無關、跨網絡可執行”軟件組件的基礎。
C++相對於精瘦的C來說,多了許多特性,正因如此,我們更有必要去探索、瞭解C++對象模型,到底揹着我們又發生了什麼事情。在瞭解C++對象模型之前,有必要先從簡單一點的兩個模型入手:簡單對象模型、表格驅動模型。
簡單對象模型
現在我們考慮一個Point類,其聲明如下:
class Point {
public:
Point(float xval);
virtual ~Point();
float x() const;
static int PointCount();
protected:
virtual ostream& print(ostream& os) const;
float _x;
static int _point_count;
};
在C++中,成員數據(class data member)有兩種:static和nonstatic,成員函數(class
member function)有三種:static、nonstatic和virtual。
那麼上述的Point類,用簡單對象模型應該怎麼塑模這些data members和function members呢,如下:
這個對象模型比較簡單,在這個簡單模型中,object中存放的並不是member而是一系列的slots,每個slot指向一個member,按member在class中的聲明順序,即object中存放的是“指向member的指針”,這就避免了因不同類型的member需要不同存儲空間所帶來的問題。
表格驅動模型
與簡單對象模型類似,但又有所不同。表格驅動對象模型將class中的member分成data和function兩個部分,一個放在data member table中,一個放在member function table中,而class object則持有指向這兩個table的指針。在往下劃分,data member table直接存放data本身,而member function table則是一系列的slots,每個slot指向一個member function,如下。
這種對象模型不會因class中data member和member function的增減而改變其大小,但在操作member function時,比data member多了一次尋址。
CPlusPlus對象模型
C++對象模型是從簡單對象模型派生而來的,並對內存空間和存取時間做了優化。在此模型中對data而言nonstatic data member被置於class object之內,static data member被置於class object之外;對function而言,static和nonstatic member function被置於class object之外,virtual member function則由以下兩步支持:
1、每一個class產生出一堆指向virtual function的指針,並存放於表格中,即virtual table(vtbl);
2、每個class object被安插一個指針(vptr),指向相關的virtual table。
上面兩點是用以支持virtual function的。在C++中,關鍵字virtual的存在只有兩處,一出現在member function之前形成virtual function,二出現在inheritance時形成virtual inheritance(虛擬繼承),若base class或derived class不是以上兩種情況,也無virtual table之說了。如下。
另外,在C++對象模型中我們可以看到vptr指向的virtual table中多了一個type_info,並且位於vtbl的第一個slot,這是用以支持rumtime type identification(RTTI)的,這個後面的學習筆記再說。vptr這個指針的設定、重置都由每一個class的constructor、destructor和copy assignment運算符自動完成。
更進一步的說,pt->vtbl[0]指向Point的type_info object,pt->vtbl[1]指向Point::~Point(),pt->vtbl[2]指向Point::print()。
參考資料:
[1] 深度探索C++對象模型,[美]Stanley B. Lippman著,侯捷譯;
[2] C++對象模型,吳秦(http://www.cnblogs.com/skynet/)