C++對象模型——關於對象(第一章)
阿新 • • 發佈:2017-05-25
poi 相同 bsp 擁有 配置 軟件 cto 之間 模式
或者,假設要想更有效率一些,就定義一個宏:
在C++中,Point3d有可能用獨立的"抽象數據類型(abstract data type)來實現:
更進一步來說,無論哪一種形式,它們都能夠被參數化,能夠是坐標類型的參數化.
程序猿看到Point3d轉換成C++之後,第一個可能會問的問題就是:加上了封裝之後,布局成本添加了多少?答案是class Point3d並沒有添加成本,三個data member直接內含在每個class object之中,就像C struct的情況一樣,而member functions盡管含在class的聲明內,卻不出如今object中,每個non-inline
member function僅僅會誕生一個函數實體,至於每個"擁有零個或者一個定義"的inline function則會在其每個使用者(模塊)身上產生一個函數實體.Point3d支持封裝性質,這一點並未帶給它不論什麽空間或運行期的不良效應.C++在布局以及存取時間上基本的額外負擔是由virtual引起,包含:
virtual function機制 用於支持一個有效率的"運行器綁定"(runtime binding)
virtual base class 用以實現"多次出如今繼承體系中的base class,有一個單一而被共享的實體"
此外,另一些多重繼承下的額外負擔,發生在"一個derived class和其第二或者後繼之base class的轉換"之間.然而,一般言之,並理由說C++程序一定比C龐大或者遲緩.
在這個簡單模型中,members本身並不被放在object之中,僅僅有"指向member的指針"才被放在object內,這麽做能夠避免"members有不同的類型,因而須要不同的存儲空間"所導致的問題.Object中的members是以slot的索引值來尋址,本例中x的索引值是6,point_count的索引值為7.一個class object的大小非常easy計算出來:"指針大小,乘以class中聲明的members數目".
盡管這個模型並沒有被應用於實際產品上,只是關於索引或slot數目的觀念,倒是被應用到C++的"指向成員的指針"(point-to-member)觀念之中.
盡管這個模型也沒有實際應用於真正的C++編譯器上,但member function table這個觀念卻稱為支持virtual functions的一個有效方案.
1.每個class產生出一堆指向virtual functions的指針,放在表格之中,這個表格被稱為virtual table(vtbl)
2.每個class object被加入了一個指針,指向相關的virtual table,通常這個指針被稱為vptr.vptr的設定和重置都由每個class的constructor,destructor和copy assignment運算符自己主動完畢,每個class所關聯的type_info object也經由virtual table被指出來,一般是放在表格的第一個slot處.
C++對象模型的主要長處在於它空間和存取時間的效率;主要缺點是。假設應用程序代碼本身並未改變,但所用的class object的nonstatic data members有所改動(可能是添加、移除或改動),那麽那些應用程序代碼相同得又一次編譯。
第一章 關於對象
在C語言中,"數據"和"處理數據的操作(函數)"是分開聲明的,也就是說,語言本身並沒有支持"數據和函數"之間的關聯性.我們把這樣的程序方法成為程序性,由一組"分布在各個以功能為導向的函數中"的算法所驅動,它們處理的是共同的外部數據.舉個樣例,假設聲明一個struct Point3d,像這樣:typedef struct point3d { float x; float y; float z; } Point3d;欲打印一個Point3d,可能就得定義一個像這種函數:
void Point3d_print (const Point3d *pd) { printf("(%g, %g, %g)", pd->x, pd->y, pd->z); }
#define Point3d_print(pd) printf("(%g, %g, %g)", pd->x, pd->y, pd->z);也可直接在程序中完畢其操作
在C++中,Point3d有可能用獨立的"抽象數據類型(abstract data type)來實現:
class Point3d { public: Point3d(float xval = 0.0, float yval = 0.0, float zval = 0.0) : x(xval), y(yval), z(zval) {} float getX() { return x; } float getY() { return y; } float getZ() { return z; } void setX(float xval) { x = xval; } private: float x; float y; float z; }; inline ostream & operator << (ostream &os, const Point3d &pt) { os << "(" << pt.getX() << ", " << pt.getY() << ", " << pt.getZ() << ")"; }
template <class type> Point3d(type xval = 0.0, type yval = 0.0, zval = 0.0);也能夠是坐標類型和坐標數目兩者都參數化:
template <class type, int dim> Point(type coords[dim]);非常明顯,不僅僅是程序風格上有截然的不同,在程序的思考上也有明顯的差異,從軟件project的眼光來看"一個ADT或者class hierarchy的數據封裝"比"在C程序中程序性使用全局數據"好.,可是這被那些"被要求高速讓一個應用程序上馬應戰,而且運行起來又快又有效率"的程序猿所忽略,畢竟C的吸引力就在於它的精瘦和簡易.
加上封裝後的布局成本(Layout Costs for Adding Encapsulation)
virtual function機制 用於支持一個有效率的"運行器綁定"(runtime binding)
virtual base class 用以實現"多次出如今繼承體系中的base class,有一個單一而被共享的實體"
此外,另一些多重繼承下的額外負擔,發生在"一個derived class和其第二或者後繼之base class的轉換"之間.然而,一般言之,並理由說C++程序一定比C龐大或者遲緩.
1.1 C++對象模式(The C++ Object Model)
在C++中,有兩種class data members:static 和 nonstatic,以及三種class member functions:static,nonstatic和virtual,已知以下這個class Point聲明:class Point { public: Point(float xval); virtual ~Point(); float getX() const; static int PointCount(); protected: virtual ostream& print(ostream &os) const; float x; static int point_count; };這個class Point在機器中會被如何表現呢?也就是說,如何模擬(modeling)出各種data members和function members呢?
1.1.1 簡單對象模型 (A Simple Object Model)
第一個模型很easy,它可能是為了盡量減少C++編譯器的設計復雜度而開發出來的,缺點則是空間和運行期的效率低下.在這個簡單模型中,一個object是一系列的slot(槽),每個slot指向一個member.Members依照聲明次序,各自被指定一個slot.每個data member或function member都有自己的一個slot.在這個簡單模型中,members本身並不被放在object之中,僅僅有"指向member的指針"才被放在object內,這麽做能夠避免"members有不同的類型,因而須要不同的存儲空間"所導致的問題.Object中的members是以slot的索引值來尋址,本例中x的索引值是6,point_count的索引值為7.一個class object的大小非常easy計算出來:"指針大小,乘以class中聲明的members數目".
盡管這個模型並沒有被應用於實際產品上,只是關於索引或slot數目的觀念,倒是被應用到C++的"指向成員的指針"(point-to-member)觀念之中.
1.1.2 表格驅動對象類型 (A Table-driven Object Model)
為了對全部classes的全部objects都有一致的表達方式,還有一種對象模型是把全部與members相關的信息抽出來,放在data member table和一個member function table之中,class object本身則內含這兩個表格的指針,Member function table是一系列的slots,每個slot指出一個member function; Data member table則直接含有data本身.盡管這個模型也沒有實際應用於真正的C++編譯器上,但member function table這個觀念卻稱為支持virtual functions的一個有效方案.
1.1.3 C++對象模型 (The C++ Object Model)
Stroustrup當初設計(當前仍占有優勢)的C++對象模型是從簡單對象模型派生而來的,並對內存空間和存取時間做了優化.在此模型中,Nonstatic data members被配置於每個class object之內,static data members則被存放在全部的class object之外,Static和nonstatic function members也被放在全部的class object之外,Virtual functions則以兩個步驟支持之:1.每個class產生出一堆指向virtual functions的指針,放在表格之中,這個表格被稱為virtual table(vtbl)
2.每個class object被加入了一個指針,指向相關的virtual table,通常這個指針被稱為vptr.vptr的設定和重置都由每個class的constructor,destructor和copy assignment運算符自己主動完畢,每個class所關聯的type_info object也經由virtual table被指出來,一般是放在表格的第一個slot處.
C++對象模型的主要長處在於它空間和存取時間的效率;主要缺點是。假設應用程序代碼本身並未改變,但所用的class object的nonstatic data members有所改動(可能是添加、移除或改動),那麽那些應用程序代碼相同得又一次編譯。
關於這點,前面的的表格驅動模型就提供了較大的彈性,由於它多提供了一層間接性。只是它也因此付出空間和運行效率雙方面的代價。
C++對象模型——關於對象(第一章)