關于對象
...引子:在C語言中,"數據"和"處理數據的操作(函數)"是分開來聲明的,語言本身并沒有支持"數據和函數"之間關聯性,這種程序成為"程序性的",由一組"分布在各個一功能為向導的函數中"的算法驅動,他們處理的是共同的外部數據.
...C++在布局以及存取時間上的主要額外負擔是有virtual引起的,包括:
? 1)virtual function 機制,用以實現一個有效率的"執行期綁定"
? 2)virtual base class 用以實現"多次出現在繼承體系中的 base class,有一個單一而被共享的實體"
1.對象模式:
1.1對象模式:
...C++中,有兩種class data members:static和nonstatic,以及三種class member functions:static,nonstatic和virtual,一共有三類C++對象模型:簡單對象模型,表格驅動對象模型,C++物件對象模型.
? 1)簡單對象模型:在此模型中一個object是由一系列的slots組成,每一個slot指向一個member,每個data member或是function member都有一個自己的slot
? 2)表格驅動模型:在此模型中,有兩個指針,一個指向data member table,另一個指向member function table,在這項兩個標志中存放著一系列slots,每一個slot指向一個data member或是一個function member.
? 3)C++物件對象模型:在此模型中,nonstatic data members被配置于每一個class object之內,static data members則被存放在所有的class object之外,static和nonstatic functions也被存放在所有的class object之外,virtual functions則有以下兩個步驟支持:
??? a)每一個class產生出一堆指向virtual functions的指針,放在表格之中,這個表格被稱為virtual table(vtbl).
??? b)每一個class object被添加了一個指針,指向相關的virtual table,通常這個指針被稱為vptr,vptr的設定和重置都有每一個class constructor,destructor和copy assignment運算符自動完成,每個vtbl的第一個slot一般都是指向type_info object.
...加上繼承:
? C++最初采用的繼承模型并不運用任何間接行:base class subobject的data members直接被置于derived class object中,在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的位置.
1.2關鍵詞struct:
..."struct那個關鍵詞,其實沒什么用"(Bell Lab)
...C++中凡是處于同一個access section的數據,必定保證以其聲明次序出現在內存布局中,然而被放置在多個access sections中的數據,排列次序就不一定有規定的順序.
...C struct在C++中的一個合理用途是,當你要傳遞"一個復雜的class object的全部或是部分"到某個C函數中去時,struct的聲明可以將數據封裝起來,并保證擁有與C兼容的空間布局,然而這項保證只在組合(composition)的情況下才存在,如果是繼承而不是組合在不行,因為編譯器會決定是否要有額外的data members被安插到base struct subobject之中.
1.3對象的差異:
...C++程序設計模型直接支持三種programming paradigms(程序設計典范):
? 1)程序模型:就像C一樣.
? 2)抽象數據類型模型:該模型所謂的"抽象"是和一組表達式(public接口)一起提供,而其運算符定義仍然隱而未明.
? 3)面向對象模型:在此模型中有一些彼此相關的類型,通過一個抽象的base class(用以提供共通接口)被封裝起來.
...C++用下列方法來支持多態:
? 1)經由一組隱含的轉化操作.
? 2)經由virtual function機制.
? 3)經由dynamic_cast和typeid運算符.
注:一般只有通過pointers或是references的間接處理,才能支持面向對象程序設計所需的多態.
...要表現一個class object需要多少內存?
? 1)其nonstatic data members的總和大小.
? 2)加上任何由于alignmennt的需求而填補的空間.(alignment就是將數值調整到某數的倍數,一般32位計算機上通產alignment為4bytes)
? 3)加上為了支持virtual而由內部產生的任何額外負擔.
...指針類型:"指向不同類型的個指針"在內存上均是一個地址,無任何差異,其不同之處在于其所尋址出來的objec類型不同,也就是說,"指針類型"會教導編譯器如何解釋摸個特定地址中的內存內容以及其大小.
...關于多態:
? 當一個base clas直接被初始化為一個derived class object時,derived object就會被切割(sliced),以塞入較小的base type內存中,于是derived將沒有留下任何痕跡,多態將不再出現.C++通過pointer或是reference來支持多態,這種程序設計風格成為"面向對象".