- C語(yǔ)言中,數(shù)據(jù)與處理數(shù)據(jù)的操作(函數(shù))是分開(kāi)聲明的,這種程序方法被稱(chēng)為程序性的;而在c++中,則是使用abstract data type(ADT)或class hierarchy的數(shù)據(jù)封裝
- c++對(duì)于結(jié)構(gòu)體和函數(shù)(不包含virtual和non-inline)的封裝并沒(méi)有增加布局成本,對(duì)于C++而言,在布局以及存取時(shí)間上主要的額外負(fù)擔(dān)是由virtual引起
- virtual function
- virtual base class
The c++ Object Model
-
c++中,有兩種class data members:static and nonstatic,和三種class member functions:static、non-static and virtual
目前成都創(chuàng)新互聯(lián)已為近1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁(yè)空間、網(wǎng)站托管、服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、靜安網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
-
現(xiàn)有以下class聲明:
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;
}
-
此 class 可以通過(guò)三種object models表示
A Simple Object Model
A Table-driven Object Model
- 將所有members的信息抽離出來(lái)放在一個(gè)member data table 和 一個(gè)member function table中,而class則含有指向這兩個(gè)table的pointer
- 意義:成為virtual function的一個(gè)方案
The c++ Object Model
- 此模型從A Simple Object Model派生而來(lái),并對(duì)內(nèi)存空間和存取時(shí)間優(yōu)化
- Nonstatic data members被配置于每一個(gè)class object內(nèi),static data members、Static function members、 nonstatic function members則被存放于個(gè)別的class object外。而用virtual functions來(lái)支持此model:
- virtual tabel(vtbl)中存放一些指向由class生成的virtual functions的pointer
- 每個(gè)class object安插一個(gè)指針(vptr),此指針指向相關(guān)的virtual table。而vptr的setting 和 resetting都有class里的constructor、destructor、copy assignment運(yùn)算符自動(dòng)完成。每個(gè)class關(guān)聯(lián)的type_info object(支持runtime type identification,RTTI)亦由virtual table指出,通常放于表格中的第一個(gè)slot
- 優(yōu)點(diǎn):空間和存取時(shí)間效率高
- 缺點(diǎn):若應(yīng)用程序本身未改變,而class內(nèi)的nonstatic data members有所修改,則應(yīng)用程序代碼需重新編譯
- c++支持單一繼承、多重繼承、虛擬繼承。虛擬繼承中,base class不管在繼承串鏈中被派生多少次,永遠(yuǎn)只存在一個(gè)實(shí)例subobject
A Keyword Distinction
- C++為了維護(hù)和C之間的兼容性,為此付出了很多犧牲
int (*pq) ();
- 當(dāng)語(yǔ)言無(wú)法區(qū)分此函數(shù)是declaration還是invocation時(shí),需要一個(gè)超越語(yǔ)言范圍的規(guī)則,此規(guī)則會(huì)將此函數(shù)判斷為declaration
- struct的一個(gè)合理用途:將class object某個(gè)數(shù)據(jù)做封裝,達(dá)到與C的兼容的空間布局,只有composition才支持
- template并沒(méi)有兼容struct
An Object Distinction
- c++程序設(shè)計(jì)模型支持三種programming paradigms:
- procedural model
- abstract data type model
- object-oriented model
- object-oriented model中,被指定的object的真實(shí)類(lèi)型在每個(gè)特定執(zhí)行點(diǎn)前無(wú)法解析,只有通過(guò)pointer 和 reference才能完成;相反,abstract data type model中,所處理的是一個(gè)固體且單一類(lèi)型的實(shí)例,真實(shí)類(lèi)型早在編譯時(shí)期就已定義,因此速度更快且空間排布更緊湊,但沒(méi)有彈性
- c++用三種方法支持多態(tài):
- 經(jīng)由一組隱式轉(zhuǎn)化。如把derived class pointer轉(zhuǎn)化為public base type的pointer
- 經(jīng)由virtual function機(jī)制
- 經(jīng)由dynamic_cast和typeid運(yùn)算符
- 多態(tài)主要用途:由一個(gè)共同的接口影響類(lèi)型封裝,此接口通常被定義在抽象的base class
- class object所需的內(nèi)存大?。?
- nonstatic data members的總和大小
- 任何由于alignment(將數(shù)值調(diào)整到某數(shù)倍數(shù))的需求而padding的空間
- 支持virtual產(chǎn)生的額外負(fù)擔(dān)
The Type of a Pointer
- "指針類(lèi)型"告訴編譯器如何解釋目的地址中的內(nèi)容和大小,這也是為什么pointer和reference支持多態(tài)
- 我們并不知道void*指針涵蓋的地址空間,因此void*的指針只含有一個(gè)地址,且不能操作所指向的object
- cast本質(zhì)上是編譯器指令,它并不改變指針?biāo)牡刂?,而只影?所指內(nèi)存的大小和其內(nèi)容"的解釋方式
Adding Polymorphism
class A
{
public:
virtual action1();
...
}
class B : public A
{
//以下皆為B獨(dú)有
public:
...
void rotate();
protected:
enum action2 {...};
int n;
}
B b;
A* p1 = &b;
B* p2 = &b;
-
顯然,我們并不不能用p1處理A以外的members,唯一方法是通過(guò)virtual
//以下都可行
(static_cast (p1))->n;
if( B*p3 = dynamic_cast(p1) ) //此為run-time operation,成本較高
p3->n;
p1->action1()
B b;
A a1 = b; //造成sliced
a1.action1(); //調(diào)用A中的
- 為什么a1中的vptr不會(huì)指向b的virtual table?
- 編譯器需確保若object含有一個(gè)或一個(gè)以上的vptrs,這些vptrs內(nèi)容不會(huì)被base class object初始化或改變
- 為什么action1()依舊是調(diào)用的A的?
網(wǎng)頁(yè)名稱(chēng):c++對(duì)象模型
網(wǎng)站網(wǎng)址:
http://weahome.cn/article/dsoiidc.html