C 的繼承,多繼承,虛繼承的物件分布的總結

2021-07-25 17:03:00 字數 2967 閱讀 9497

根據幾篇部落格c++物件模型,c++涉及繼承和虛繼承時的記憶體布局 ,c++ 物件的記憶體布局(上) 作了一些歸納和總結,留著備用吧。

討論問題:

先看單繼承的例子:

#include

using

namespace

std;

class parent

virtual

void f()

virtual

void g()

};class child : public parent

virtual

void f()

virtual

void h()

virtual

void gc()

};class grandchild : public child

virtual

void f()

virtual

void ggc()

virtual

void gc()

};

單繼承的記憶體分布:

單繼承(非虛繼承)基本上繼承父類的 vptr,並且會將自己的類的虛函式直接新增在子類的vptr,是一種 「is a 」的關係,可以共用vptr,而且物件成員變數也相應的繼承過來。

using namespace std;

class b

virtual

void f()

virtual

void bf()

};class b1 : virtual

public b

virtual

void f()

virtual

void f1()

virtual

void bf1()

};class b2: virtual

public b

virtual

void f()

virtual

void f2()

virtual

void bf2()

};class d : public b1, public b2

virtual

void f()

virtual

void f1()

virtual

void f2()

virtual

void df()

};

多繼承的物件分布:

多繼承也基本類似單繼承,只不過多了幾張虛函式表,位置是根據多繼承宣告的順序。第一張虛表還安插自己類的虛函式。每個表後面就是繼承子類的成員變數。很明顯,如果多繼承的基類有共同的 「基基類」,必然就有2份「基基類」成員

如果上面的多繼承的基類(b1,b2)虛繼承b,那麼分布就是如下:

從圖上可以看出,多了額外的一張虛表 就是 「基基類」的虛表,虛繼承是一種「has a」的關係,不是is-a關係,會儲存自己的一張虛表和成員,後續派生的資料成員也是只有乙份。

注意:vs上,在b1和b2的 vptr和成員之間位置,會新增虛基類指標vbptr(可能是偏移位址或者直接位址),而clang和gcc沒有,其他編譯器實現不清楚,有些編譯器可能將虛基類的偏移位址 安插到虛函式表指標中(正偏移為虛函式,負為虛基類)

這裡對於虛線框處,inside object c++ model 說對於虛基類會有乙個 基類表指標,指向虛基類的偏移或者虛基類的位址,這裡本人在實驗的時候,並沒有發現 vbptr,vs似乎會生成在vptr和成員變數之間。

棕色部分根據編譯器實現而定,vs上似乎會生成(放在vptr和成員變數之間),gcc和clang沒有這部分。

注意:vs上,在b1和b2的 vptr和成員之間位置,會新增虛基類指標vbptr(可能是偏移位址或者直接位址),而clang和gcc沒有,其他編譯器實現不清楚,有些編譯器可能將虛基類的偏移位址 安插到虛函式表指標中(正偏移為虛函式,負為虛基類)

測試**:

機器在64位:指標為8bytes,而且按8bytes對齊方式

#include 

using

namespace

std;

class base

virtual

void g()

virtual

void h()

long b=1;

};class base2:virtual base

virtual

void g()

virtual

void gb2()

long b=2;

};class base3:virtual base

virtual

void g()

virtual

void gb3()

long b=3;

};class derive:public base2,public base3

virtual

void g()

virtual

void gb4();

long b=20;

};int main()

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

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

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

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

C 多繼承 虛繼承

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