根據幾篇部落格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 最後是自己的構造器 二,...