深度探索C 物件模型 Data語義學

2021-06-23 02:37:58 字數 2025 閱讀 4929

1 data member的繫結

對於下圖的類:

x()中的x返回的是類內部的x,這是因為編譯器對於這個的處理是,如果乙個inline函式在類宣告之後立刻被定義,但還是在整個類宣告完成之後,才隊這個成員函式的本體進行分析,所以x繫結的是類內部的x

然而對於成員函式的引數列表則不是這樣的,它們會在第一次遇見時被決議。例如如果類中有nested type names,而函式有引數列表有該型別的引數,但是這個類內的型別定義卻在這個函式之後,則會出現錯誤。例如下面這個類的效果。

像以上這個例子,後面的length的定義會使前面的參考操作不合法。

所以解決方法是,將「nested type 宣告」放在類的開始處,就不會出現上述錯誤了。所以如果類中有自定義的結構體,而函式引數是結構體型別,則這個函式要在這個結構體定義之後定義才合法,否則是錯誤的。

2 data member的布局。

成員布局:非靜態成員在類物件的排列順序與宣告順序一樣,任何static成員如上面的freelist, chunksize都不會放進物件布局。他們存放在程式的data segment中。

但是同一種訪問型別中的資料成員只符合「較晚出現的成員在類物件中有較高位址」,但是類資料成員間不一定連續,可能會有別的,例如為了對齊新增的一些bytes,還有就是編譯器合成的vptr,這個一般被放在類物件成員的最後,但是有的編譯器在最前。一般編譯器都將乙個以上的access sections連鎖在一起,依照宣告順序連成區域,這些access sections的多少並不會招來其他負擔。

3 data member的訪問

point3d origin;

origin.x = 0.0

point3d origin, *pt =&origin;

origin.x=0.0;

pt->x = 0.0

上面兩種經過物件和指標訪問x的存在的差異:當point3d是乙個繼承類,而且繼承結構中有乙個虛基類,而且x是從虛基類繼承而來的成員,有重大差異。因為不知道pt指向哪個類型別,所以也不能在編譯器確定,要延遲到執行器。當然這是發生在指標pt訪問,如果origin訪問沒有什麼問題。

分兩類討論,有一點:類的訪問許可,以及與類的關聯,不會隊成員的訪問招致任何空間和時間的額外負擔。

(1)靜態資料成員,被視為全域性變數,因為靜態成員不在類物件中,所以訪問靜態成員不需要經過類物件,而且不管是有多麼複雜的繼承關係繼承過來的,都一樣。

而且訪問乙個靜態成員的指標,會得到乙個指向其資料型別的指標,而不是指向類成員的指標。

如果有兩個類有相同的靜態成員變數,則在資料段有名稱衝突,解決方法就是暗中隊每個變數編碼(name-mangling,就是通過乙個演算法推導出乙個獨一無二的名稱)

(2)非靜態資料成員,類中每次對非靜態資料成員的訪問,都會通過this指標訪問,而且編譯器需要把類物件的起始位址夾生資料成員的offset

origin._y = 0.0

=>&origin+(&point3d::_y-1)

指向資料成員的指標,offset值總是被加上1,以便編譯器區分出「指出類的第乙個成員的資料成員的指標」和「沒有指出任何成員的資料成員的指標」。。這以後有詳細說明

而且這個offset是在編譯期可以缺點的,甚至成員是基類子對下的成員也一樣,所以訪問乙個非靜態成員,效率和訪問乙個c struct或非繼承類的成員是一樣的。

point3d *pt3d;

pt3d->x = 0.0

在 x是乙個struct member, 乙個class member,單一繼承,多重繼承都是一樣的,但是如果是乙個虛基類的成員,訪問速度會稍慢。

深度探索c 物件模型(3) data

空基類的大小為1byte,為了讓不同的空型別的位址有區別 一 data member的布局 nonstatic member data按宣告順序存在class object中 static member data位於global data segment 不會影響object大小 對static m...

深度探索C 物件模型 Data語意學筆記

class x class y public virtual x class z public virtual x class a public y,public z 它們的sizeof結果如下 sizeof x 1 sizeof y 8 視編譯器不同而不同 sizeof z 8 視編譯器不同而不同...

深度探索C 物件模型學習筆記 Data語意學

例子 class x class y public virtual x class z public virtual x class a public y,public z 物件大小由下述原因決定 1.語言本身所造成的額外負擔 如 支援virtual base classes時,derived cl...