深刻懂得C++的對象模子。本站提示廣大學習愛好者:(深刻懂得C++的對象模子)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻懂得C++的對象模子正文
作甚C++對象模子?
C++對象模子可以歸納綜合為以下2部門:
1. 說話中直接支撐面向對象法式設計的部門
2. 關於各類支撐的底層完成機制
引言
如今有一個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;
};
這個類在機械上是經由過程甚麼模子來表現的呢?上面就引見三種分歧的完成方法。
1. 簡略對象模子
簡略對象模子名不虛傳,非常簡略。在簡略對象模子中,一個 object是由一系列slots構成,每一個slot相當於一個指針,指向一個member,memebers依照聲明的次序與slots逐個對應,這裡的members包括data members和function members。
假如將簡略對象模子運用在Point Class上,構造圖以下:
長處:非常簡略,下降了編譯器設計的龐雜度。
缺陷:空間和時光上的效力下降。因為一切member都對應一個slot指針,所以每一個object在空間上額定多出:member's number 乘以指針年夜小的空間。同時因為拜訪object的每一個member都須要一次slot的額定索引,所以在時光的效力也會下降。
2. 表格驅動對象模子
表格驅動對象模子將member data和member function分離映照成兩個表格member data table和function member table,而object自己只存儲指向這兩個表格的指針。 個中function member table是由一系列的slot構成,每一個slot指向一個member function; member data table則直接存儲的member data自己。假如將表格驅動對象模子運用在Point Class上,構造圖以下:
長處:采取兩層索引機制,對object變更供給比擬好的彈性,在object的nonstatic data member有所轉變時,而運用法式代碼沒有轉變,這時候是不須要從新編譯的。
缺陷:空間和時光上的效力下降,詳細緣由可以參考簡略對象模子的缺陷剖析。
3. C++ 對象模子
Stroustrup 晚期設計的C++對象模子是從簡略對象模子改良而來的,並對內存空間和存取時光停止了優化。重要是將nonstatic data members存儲在每個object中,而static data members和一切的function members被自力存儲在一切object以外。
對虛函數的支撐重要經由過程以下幾點完成的:
一切包括虛函數或許繼續自有虛函數基類的class都邑有一個virtual table,該虛函數表存儲著一堆指向該類所包括的虛函數的指針。
每一個class所聯系關系的type_info object也是由virtual table存儲的,普通會存在該表格的首個slot,type_info用於支撐runtime type identification (RTTI)。
假如將C++對象模子運用在Point Class上,構造圖以下:
長處:空間和存取效力高,一切static data members和一切的function members被自力存儲在一切object以外,可以削減每一個object的年夜小,而nonstatic data members存儲在每個object中,又晉升了存取效力。
缺陷:假如運用法式的代碼不曾更改,但所用到的class的nonstatic data members有所更改,那末那些代碼依然須要全體從新編譯,而後面的表格驅動模子在這方面供給了較年夜的彈性,由於他多供給了一層直接性,固然是支付了時光和空間上的價值。
在加上繼續情形下的對象模子
C++支撐單繼續、多繼續、虛繼續,上面來看下base class實體在derived class中是若何被構建的。
簡略對象模子中可以經由過程derived class object中的一個slot來存儲base class subobject的地址,如許便可以經由過程該slot來拜訪base class的成員。這類完成方法的重要缺陷是:由於直接性的存儲而招致空間和存取時光上存在額定累贅;長處是:derived class的構造不會由於base class的轉變而轉變。
表格驅動對象模子中可以應用一個相似base class table的表格來存儲一切基類的信息。該表格中存儲一系列slot,每一個slot存儲一個base class的地址。這類完成方法的缺陷是:由於直接性的存儲而招致空間和存取時光上存在額定累贅;長處是:一是一切繼續的class都有分歧的表示情勢(包括一個base table指針,指向基類表)與基類的年夜小和數量沒有關系,二是base class table增長了子類的擴大性,當基類產生轉變時,可以經由過程擴大、減少或許更改base class table來停止調劑。
以上兩種完成方法都存在一個主要的成績,就是因為直接性而招致的空間和時光上的額定累贅,而且該直接性的級數會跟著繼續的深度而增長。
C++ 最後采取的繼續模子其實不采取任何直接性,一切基類的數據直接存儲在子類傍邊,如許在存儲構造和拜訪效力上是最高效的。固然也出缺點:當base class members有任何轉變,用到此base class或許derived class的對象必需從新編譯。在C++ 2.0引入了virtual base class,須要一些直接性的方法來支撐該特征,普通會導入一個virtual base class table或許擴大已有的virtual table。
總結
以上就是深刻研討C++的對象模子的全體內容,願望本文的內容對年夜家有所贊助。