C 中的菱形繼承和虛繼承簡述

2021-10-10 06:43:08 字數 1711 閱讀 8275

多繼承概念:

我們可以從乙個類繼承,我們也可以能同時從多個類繼承,這就是多繼承。但是由 於多繼承是非常受爭議的,從多個類繼承可能會導致函式、變數等同名導致較多的 歧義。

如以下所示,訪問變數時候要加上作用域,表示訪問的是哪個變數和函式

#include

#include

using

namespace std;

class

test_a

void

fun2()

public

:int test;};

class

test_b

int test;

int a;};

class

test

:public test_a,

public test_b

;void

test01()

intmain()

執行結果:

注:多繼承會帶來一些二義性的問題, 如果兩個基類中有同名的函式或者變數,那麼 通過派生類物件去訪問這個函式或變數時就不能明確到底呼叫從基類 1 繼承的版 本還是從基類 2 繼承的版本? 解決方法就是顯示指定呼叫那個基類的版本。

菱形繼承和虛繼承

概念:兩個派生類繼承同乙個基類而又有某個類同時繼承者兩個派生類,這種繼承被稱為 菱形繼承,或者鑽石型繼承。

通俗來講:就是乙個大的基類,被兩個派生類繼承了它的函式和變數,此時又有乙個派生類同時繼承了這兩個派生類的函式和變數。

我們從概念可以知道,最後的派生類繼承了兩份大基類的成員。(它繼承的兩個派生類每乙個都繼承了乙份大基類的成員)

此時訪問最後的派生類成員時候會產生二義性,雖然可以通過指定派生類名來限制訪問的成員,但是還有乙個重複繼承的問題,所以c++提供了乙個虛繼承的概念來同時解決二義性和重複繼承問題。

#include

#include

using

namespace std;

class

base};

class

test_a

:virtual

public base

;class

test_b

:virtual

public base

;class

test

:public test_a,

public test_b

;void

test01()

intmain()

虛繼承實現的基本原理:虛繼承底層實現原理與編譯器相關,一般通過虛基類指標和虛基類表實現,每個虛繼承的子類都有乙個虛基類指標(任何型別的指標變數都是占用4個位元組)和虛基類表(不占用類物件的儲存空間)(需要強調的是,虛基類依舊會在子類裡面存在拷貝,只是僅僅最多存在乙份而已,並不是不在子類裡面了);當虛繼承的子類被當做父類繼承時,虛基類指標也會被繼承。

實際上,vbptr指的是虛基類表指標,該指標指向了乙個虛基類表,虛表中記錄了虛基類與本類的偏移位址;通過偏移位址,這樣就找到了虛基類成員,而虛繼承也不用像普通多繼承那樣維持著公共基類(虛基類)的兩份同樣的拷貝,節省了儲存空間。

菱形繼承和菱形虛繼承

繼承是c 的一大特點,我們通過菱形繼承和菱形虛繼承對繼承進行進一步的分析。菱形繼承 建立乙個基類a讓b1和b2公有繼承於它,讓c公有繼承b1和b2。class a a int a class b1 public a b1 int b1 class b2 public a b2 int b2 clas...

c 中菱形繼承 虛繼承

關於菱形繼承 相當於在c 中,分別建立四個類,動物類,羊類,駝類,羊駝類,繼承關係如圖所示。在類中只建立乙個屬性,年齡。動物類 class animal 羊類 class sheep virtualpublic animal 駝類 class tuo virtualpublic animal 羊駝類...

菱形繼承和虛繼承

1.菱形繼承 菱形繼承概念圖 菱形繼承物件模型 參照菱形繼承物件模型,不難發現若呼叫dd類時,裡面包含兩個相同的aa類的所有成員,在呼叫過程中會出現二義性和資料冗餘的問題,為了解決上述問題,我們提出了虛繼承。接下來通過簡單例項 講解虛函式及底層實現。樣例 include using namespac...