c++ object model
對一個結構體進行不斷的封裝后可以形成一個c++類,為此需要添加很多函數成員之類的代碼,為此顯示c++比c語言顯得龐大并且遲緩,但是事實并不是這些
c++在布局和時間上的額外承擔主要是由virtual引起的
下面簡述c++對象模型
數據成員包括靜態成員和非靜態成員,
函數成員包括靜態,非靜態,虛函數
--------------------------------------------
c++對象模型
?
(1)簡單對象模型
每一個對象存儲著若干個slots,每一個slots指向一個成員,這里面包括函數成員和數據成員,對于順序,索引則按照他們的聲明順序進行排序
這樣每一個成員都不存儲在對象中,而是通過對象內的一個slots指針指向自己,這樣可以解決因為數據成員的類型不同,而需要開辟不同的空間而導致的不必要的麻煩
這種模式很少被應用到工業中,但是slots得思想和索引的概念影響著其他的模型
?
(2)表格驅動對象模型(雙表格模型)
此種模型將所有的數據成員抽象出來,講date member直接存儲放在一個表中,而member function 的slots放在另外一個表中,我們對象本身只有兩個指針,一個指針指向數據成員,一個指針指向函數成員表,表中有一系列的slots,在通過slots找到各個函數,這里的機制就類似于簡單對象模型
?
(3)c++對象模型:
此模型主要在簡單模型的基礎上進行了一些列的優化,首先對于數據成員:非靜態的直接存儲在object內部,對于靜態的則存儲在class外,
對于函數成員來說,靜態成員函數和非靜態成員函數也都存在類之外,對于虛函數(每一個object產生一個指針,指向virtual table,這個table內有一些列slots,分別指向各個虛函數)
?
優缺點:這個模型在存取時間和空間上的效率得到了改善,但是如果非靜態數據成員進行了更改,那么程序需要重新編譯。和雙表格模型比較,其空間效率和時間更好,但是雙表格模型由于中間又一次間接引用,所以即使非靜態數據成員進行了更改,也沒有問題,其彈性比較好
?
如果再次基礎上,加上了繼承的話,
那么我們可以在每一個object中增加一個bptr指針,每一個指針指向一個base table,table里面有一些列的slots,每一個slots指向一個base function
上面方法的缺點就是隨著繼承深度的增加,間接性的尋址,隨著深度的增加時間也在增減,其時間和空間都消耗許多
優點就是其對于每一個object的繼承方式都表現為一致性,無需改變class本身,都可以改變base class table,class object只需要一個bptr指向其base table就ok了
?
*****在c++對象模型的virtual table中的第一個索引是一個type_info for class 這這標記表示了我這個對象指向了哪一個類
eg:
A *P =NEW A() ?
A*P=new B()
第一種就是指向A,第二種就是指向B
?
?
但是對于c++對象模型來說,很多成員函數和靜態成員都獨立于對象存儲,那么我們怎么找到他
?
對于static date member
它被編譯器提出于class之外,并被視為一個global變量(但只在class生命范圍之內可見)
每個靜態數據成員只有一個實體,存放在程序的數據段之中,
經由’.’運算符,對一個靜態數據成員進行存取操作,只是語法上的一種便宜行事而已。靜態數據成員其實并不在class object之中,因此存取它并不需要通過class object。
雖然你可以不靠class object?來存取一個靜態成員,但其存取函數卻得綁定于一個class object之上。(若靜態成員的訪問控制為protected或private,則必須通過存取函數來訪問)
?
?
成員函數的處理
C++的設計準則之一:非靜態成員函數至少和一般的外部函數有相同的存儲效率。
C++編譯器會把成員函數內化為一般的函數:
①改寫函數原型,安插一個額外的參數this指針。用以提供一個存取管道,使類對象得以調用該函數。
int A::foo (A* const this)
若該成員函數是const,則變成:
int A::foo (const A* const this)
②對函數體中 類對象的非靜態數據成員的存取操作,改為經由this指針來存取。
int A::foo (A* const this)
{??????????? return? this->val ;???????????? }
③將成員函數重新寫成一個外部函數,對函數名稱進行處理,使它在程序中成為獨一無二的。
A objA ; A * ptr = & objA ; ptr->foo( ) ; objA.foo() ; //分別被轉換為: foo_intA( ptr ) ; foo_intA( & objA ) ;靜態成員函數的主要特征是它沒有this指針,但是他仍然需要改一個新的函數名
故其:
①它不能夠直接存取其class中的非靜態成員
②它不能夠直接被聲明為const、virtual
③它不需要經由class object才被調用——雖然大部分時候它是這樣被調用的。
?
?因為不需要this指針,所以他等同于外部函數,只不過他的內部操作成員都是類內的static data member
?
轉載于:https://www.cnblogs.com/13224ACMer/p/6284044.html
總結
以上是生活随笔為你收集整理的c++ object model的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSDN专訪:大数据时代下的商业存储
- 下一篇: PHP的错误处理机制