虛基類指標vbptr和虛函式指標vfptr

2021-09-02 22:22:52 字數 3013 閱讀 1738

1.問題:多重繼承 ==》 派生類物件中記憶體重複 ==》 訪問衝突 記憶體浪費

2.解決:對出現多份的資料在最近的繼承前加viture

3.虛繼承時,虛基類指標vbptr指向虛基類表vbtable,虛基類表中存放的就是資料相對於虛基類指標的偏移,從而根據偏移找到資料

vbptr ==> vbtable

vbtable 中:

0 當前最近作用域的偏移 - vbptr的偏移

1 虛繼類資料的起始偏移 - vbptr的偏移

虛基類構造優先順序大於普通基類

記憶體布局:先非虛基類,後 虛基類

1.

class a

public:

int ma;

};class b: virtual public a

public:

int mb;

};class c : virtua public a

public:

int mc;

};class d : public b, public c

public:

int md;

};當a為虛基類,虛繼承於b.c時:

若為多繼承時,記憶體布局如下:

虛繼承的記憶體布局如下:

};

當a為虛基類,虛繼承於b.c時且e虛繼承d:

若為多繼承時,記憶體布局如下:

虛繼承的記憶體布局如下:

第乙個vbptr 存放3個資料,因為指標合併,向距離作用域最近的指標內層合併

};當a為虛基類,虛繼承於b時且b虛繼承d

若為多繼承時,記憶體布局如下:

虛繼承的記憶體布局如下:

第乙個vbptr 存放3個資料,因為他代替的是b這個虛基類,c中的a沒有vbptr,因為c沒有虛繼承a,只有b虛繼承a,所以只有b的a可被替換成vbptr

構造順序:

先是非虛基類,後虛基類

a->c->a->b->e->d

先構造c,c裡有基類a,先構造基類a,後c,同理a,b,最後e.d

析構順序與構造順序相反

編譯期間,系統會新增乙個隱藏成員vfptr

基類指標引用指向或者引用派生類物件時,一定要將基類的析構寫成虛函式

1.虛函式和虛繼承的對比

class base

void show(){}

public:

int mb;

};class derive : virtual public base

virtual void show(){}

public:

int md;

};

多繼承記憶體布局:

虛繼承記憶體布局:

2、成為虛函式的條件:

1.要能取位址

2.依賴物件呼叫

建構函式 不可以 系統呼叫 不依賴物件呼叫

析構函式 可以

內聯函式 不可以 不能取位址 函式在呼叫點直接展開

static函式 不可以 無this指標 不依賴物件呼叫

3、虛函式表:

第一行:rttl(run time type information)執行時型別資訊

第二行:虛函式指標的偏移

第三行:虛函式的入口位址

虛表的寫入時機 建構函式的執行之前

虛函式指標和虛基類指標

上述部落格給出了以下結論 每個類都有虛指標和虛表 如果不是虛繼承,那麼子類將父類的虛指標繼承下來,並指向自身的虛表 發生在物件構造時 有多少個虛函式,虛表裡面的項就會有多少。多重繼承時,可能存在多個的基類虛表與虛指標 如果是虛繼承,那麼子類會有兩份虛指標,乙份指向自己的虛表,另乙份指向虛基表,多重繼...

虛基類 虛函式和純虛基類

首先看乙個例子 class base class child1 public base class child2 public base void main else p print 函式呼叫的時候,檢視虛表,根據p的位址首先從虛表裡面查詢要呼叫的函式 這裡呼叫child2的print 函式 ret...

虛基類 虛函式 純虛函式和抽象類

一 虛基類 在 多繼承 中講過的例子中,由類a,類b1和類b2以及類c組成了類繼承的層次結構。在該結構中,類c的物件將包含兩個類a的子物件。由於類a是派生類c兩條繼承路徑上的乙個公共基類,那麼這個公共基類將在派生類的物件中產生多個基類子物件。如果要想使這個公共基類在派生類中只產生乙個基類子物件,則必...