c++中乙個類中無非有四種成員:靜態資料成員和非靜態資料成員,靜態函式和非靜態函式。
1.非靜態資料成員被放在每乙個物件體內作為物件專有的資料成員。
2.靜態資料成員
被提取出來放在程式的靜態資料區內,為該類所有物件共享
,因此只存在乙份。
3.靜態和非靜態成員函式
最終都被提取出來放在程式的**段中並為該類所有物件共享
,因此每乙個成員函式也只能存在乙份**實體。在c++中類的成員函式都是儲存在靜態儲存區中的 ,那靜態函式也是儲存在靜態儲存區中的,他們都是在類中儲存同乙個憊份。
因此,構成物件本身的只有資料
,任何成員函式都不隸屬於任何乙個物件,非靜態成員函式與物件的關係就是繫結,繫結的中介就是this指標
。成員函式為該類所有物件共享,不僅是處於簡化語言實現、節省儲存的目的,而且是為了使同類物件有一致的行為。同類物件的行為雖然一致,但是操作不同的資料成員。
#include"iostream.h"
class a
void print()};
void main()
4.單繼承的物件的記憶體布局
,第乙個為
虛
函式
表
指標vtbl,其後為成員且先基類後子類,虛函式表裡包含了所有的虛函式的位址,以null結束。虛函式如果子類有重寫,就由子類的重新的代替。
《一》
上述類圖的解釋:b的v2覆蓋了a的v2,c的v1覆蓋了a的v1,c的v3覆蓋了b的v3.
注意:發生覆蓋的特徵有:
1) 不同的範圍(分別位於派生類與基類
);2)函式名字相同
;3)引數相同
;4) 基類函式必須有virtual關鍵字。
成員函式被過載的特徵
(1)相同的範圍(在同乙個類中
);(2)函式名字相同;
(3)引數不同;
(4)virtual關鍵字可有可無。
「隱藏
」是指派生類的函式遮蔽了與其同名的基類函式
,規則如下
(1)如果派生類的函式與基類的函式同名,但是引數不同
。此時,不論有無virtual關鍵字,基類的函式將被隱藏(注意別與過載混淆)。
(2)如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual 關鍵字
。此時,基類的函式被隱藏(注意別與覆蓋混淆)
《二》
類c的物件的記憶體模型為:
單繼承的物件的布局,第乙個為虛函式表指標vtbl,
其後為成員且先基類後子類,
虛函式表裡包含了所有的虛函式的位址,
以null結束。
虛函式如果子類有重寫,就由子類的重新的代替。
5.與單繼承相同的是所有的虛函式都包含在虛函式表中,所不同的多重繼承有多個虛函式表
,當子類對父類的虛函式有重寫時
,子類的函式替換
父類的函式在對應的虛函式位置
,當子類有新的虛函式時
,這些虛函式被加在第乙個虛函式表的後面
《一》
對類圖的解釋:d的v3覆蓋了b3的v3,另外d有乙個新的虛函式vd。
《二》class d
的記憶體模型
總結:與單繼承相同的是所有的虛函式都包含在虛函式表中,所不同的多重繼承有多個虛函式表,當子類對父類的虛函式有重寫時,子類的函式覆蓋父類的函式在對應的虛函式位置,當子類有新的虛函式時,這些虛函式被加在第乙個虛函式表的後面
6.虛繼承,使公共的基類在子類中只有乙份,我們看到虛繼承在多重繼承的基礎上多了vbtable來儲存到公共基類的偏移。
《一》
類圖的解釋:d2覆蓋了b的vb,gd覆蓋了d1的vd1同時也覆蓋b的vb,gd也有自己的虛函式vgd。
《二》class gd的記憶體模型
總結:虛繼承,使公共的基類在子類中只有乙份,我們看到虛繼承在多重繼承的基礎上多了vbtable來儲存到公共基類的偏移
C 物件的記憶體分布和虛函式表
c 中乙個類中無非有四種成員 靜態資料成員和非靜態資料成員,靜態函式和非靜態函式。1.非靜態資料成員被放在每乙個物件體內作為物件專有的資料成員。2.靜態資料成員被提取出來放在程式的靜態資料區內,為該類所有物件共享,因此只存在乙份。3.靜態和非靜態成員函式最終都被提取出來放在程式的 段中並為該類所有物...
C 物件的記憶體分布和虛函式表
c 物件的記憶體分布和虛函式表 c 中乙個類中無非有四種成員 靜態資料成員和非靜態資料成員,靜態函式和非靜態函式。1.非靜態資料成員被放在每乙個物件體內作為物件專有的資料成員。2.靜態資料成員被提取出來放在程式的靜態資料區內,為該類所有物件共享,因此只存在乙份。3.靜態和非靜態成員函式最終都被提取出...
C 物件記憶體分布(包括位元組對齊和虛函式表)
1 c 物件的記憶體分布和虛函式表 注意,物件中儲存的是虛函式表指標,而不是虛函式表,虛函式表在編譯階段就已經生成,同類的不同物件中的虛函式指標指向同乙個虛函式表,不同類物件的虛函式指標指向不同虛函式表。2 何時進行動態繫結 1 每個類物件在被構造時不用去關心是否有其他類從自己派生,也不需要關心自己...