C 物件模型 單繼承,多繼承,虛繼承

2021-10-23 20:32:02 字數 3495 閱讀 8551

有兩個概念可以解釋c++物件模型:

語言中直接支援物件導向程式設計的部分。

對於各種支援的底層實現機制。

資料成員分為靜態和非靜態,成員函式有靜態非靜態以及虛函式

class data members:static和nonstatic

class data functions:static、nonstatic和virtual

比如:

class base

;int geti()

static

void

counti(){};

virtual

void print(void)

virtual ~base(){}

private:

intbasei;

static

intbases;

簡單物件模型:這個模型非常地簡單粗暴。在該模型下,物件由一系列的指標組成,每乙個指標都指向乙個資料成員或成員函式,也即是說,每個資料成員和成員函式在類中所佔的大小是相同的,都為乙個指標的大小。這樣有個好處——很容易算出物件的大小,不過賠上的是空間和執行期效率。所以這種物件模型並沒有被用於實際產品上。

**驅動物件模型:把類中的資料分成了兩個部分:資料部分與函式部分,並使用兩張**,一張存放資料本身,一張存放函式的位址(也即函式比成員多一次定址),而類物件僅僅含有兩個指標,分別指向上面這兩個表。這樣看來,物件的大小是固定為兩個指標大小。這個模型也沒有用於實際應用於真正的c++編譯器上。

c++物件模型:正在使用的

在此模型下,nonstatic 資料成員被置於每乙個類物件中,而static資料成員被置於類物件之外。static與nonstatic函式也都放在類物件之外,而對於virtual 函式,則通過虛函式表+虛指標來支援:

每個類生成乙個**,稱為虛表(virtual table,簡稱vtbl)。虛表中存放著一堆指標,這些指標指向該類每乙個虛函式。虛表中的函式位址將按宣告時的順序排列

每個類物件都擁有乙個虛表指標(vptr),由編譯器為其生成。虛表指標的設定與重置皆由類的複製控制(也即是建構函式、析構函式、賦值操作符)來完成。vptr的位置為編譯器決定,傳統上它被放在所有顯示宣告的成員之後,不過現在許多編譯器把vptr放在乙個類物件的最前端(也就是說物件的位址就是vptr的位址)

虛函式表的前面設定了乙個指向type_info的指標,用以支援rtti(run time type identification,執行時型別識別)。rtti是為多型而生成的資訊,包括物件繼承關係,物件本身的描述等,只有具有虛函式的物件在會生成。

原則:

對普通單繼承而言

子類與父類擁有各自的乙個虛函式表

若子類並無overwrite父類虛函式,用父類虛函式

若子類重寫(overwrite)了父類的虛函式,則子類虛函式將覆蓋虛表中對應的父類虛函式

若子宣告了自己新的虛函式,則該虛函式位址將擴充到虛函式表最後

1 #include 2 using namespace std;

3 4 class base

5 8 virtual void fun2()

9 private:

10 int a;

11 };

12 13 class derive : public base

14 17 virtual void fun3(){}

18 private:

19 int b;

20 };

21 22 int main()

23

輸出:除錯:

物件模型:

事實上vs除錯並不能看到完整資訊(比如virtual fun3以及之後提到到虛基類指標),正確的應該是

這裡講的是不考慮菱形繼承的多繼承,因為菱形繼承需要用到虛繼承,放到之後考慮

原則:

若子類新增虛函式,放在宣告的第乙個父類的虛函式表中

若子類重寫了父類的虛函式,所有父類的虛函式表都要改變:如fun1

記憶體布局中,父類按照其宣告順序排列

1 #include 2 using namespace std;

3 4 class base1

5 8 private:

9 int m_base1;

10 };

11 12 class base2

13 16 virtual void fun2(){}

17 private:

18 int m_base2;

19 };

20 21 class derive : public base1,public base2

22 25 virtual void fun3(){}

26 private:

27 int m_derive;

28 };

29 30 int main()

31 8 virtual void fun2(){}

9 private:

10 int m_base;

11 };

12 13 class derive : virtual public base

14 17 virtual void fun3(){}

18 private:

19 int m_derive;

20 };

21 22 int main()

23

物件模型:

菱形虛繼承是多繼承和虛繼承的復合,直接畫乙個物件模型吧:

筆記原圖:

參考:圖說c++物件模型:物件記憶體布局詳解

C 物件模型 單繼承,多繼承,虛繼承

有兩個概念可以解釋c 物件模型 語言中直接支援物件導向程式設計的部分。對於各種支援的底層實現機制。資料成員分為靜態和非靜態,成員函式有靜態非靜態以及虛函式 class data members static和nonstatic class data functions static nonstati...

繼承(單繼承 多繼承 菱形繼承 虛繼承)

一 單繼承 單繼承是一種 乙個子類只有乙個直接父類 的繼承關係。二 多繼承 多繼承是一種 乙個子類有兩個或兩個以上直接父類 的繼承關係。三 菱形繼承 菱形繼承由兩個 或以上 單繼承,乙個多繼承構成,結構如下 顯然,上例中assistant類多繼承了student和teacher兩個類,而studen...

C 多繼承 虛繼承

一,多繼承 include include using namespace std class b1 繼承類c void main 主函式 c類按照順序繼承b2,b1,b4,b3 再按照資料成員定義順序 memberb1,memberb4,memberb3,memberb2 最後是自己的構造器 二,...