繼承 多繼承 菱形虛擬繼承

2021-08-04 05:10:53 字數 2157 閱讀 9766

繼承

繼承是由父類和子類(或稱之為基類與派生類)兩種角色構成,子承父業,就是說派生類會繼承基類的所有的成員,並擁有自己特有的成員。

用一段**來解釋說明繼承關係

#include 

using

namespace

std;

class base

//基類

;class derived:public base//以共有繼承方式繼承於base,許可權不寫預設為private

的派生類

private:

int _d;

};int main()

執行結果如下圖所示:

先建立乙個派生類物件,執行結果中呼叫了派生類和基類的建構函式,說明,派生類繼承了基類的成員函式和成員變數,在這裡雖然繼承了成員變數可以在派生類內直接訪問,但是其他繼承許可權則不然,下面會有相關介紹

若將許可權等級排序一下:public>protected>private,則繼承之後派生類繼承於基類的成員許可權將會發生降級,繼承關係如下所示:

1.子類物件可以賦值給父類物件(切割/切片)

2. 父類物件不能賦值給子類物件

3. 父類的指標/引用可以指向子類物件

4. 子類的指標/引用不能指向父類物件(可以通過強制型別轉)

物件模型: 派生類物件模型中,繼承於基類的結構在前,屬於自身的結構在後;

乙個子類有兩個或以上直接父類時稱這個繼承關係為多繼承

如上圖所示,在菱形繼承中,因為c1、c2同時繼承base,所以在d中會存在二義性問題,也就是d同時存在兩個來自base中的成員,這是我們引入乙個虛擬繼承的方法來解決二義性問題,稱之為菱形虛擬繼承

首先他的**實現如下(virtual):

#include 

using

namespace

std;

class b

;class c1:virtual

public b//繼承於base

;class c2:virtual

public b

;class d:public c1,public c2

;int main()

以上**中呼叫構造與析構時分別列印呼叫到的函式名,virtual是要加在菱形繼承的上半部分,也就是c1、c2繼承base的時候,我們先來對比一下虛擬繼承與非虛擬繼承的執行結果的區別

<1>虛擬繼承            <2>非虛擬繼承

1. 虛擬繼承少呼叫了一次構造和一次析構

2. 虛繼承解決了在菱形繼承體系裡面子類物件包含多份父類物件的資料冗餘和浪費空間的問題。

在d的構造中,d的物件模型中有如下操作:

那麼這兩個壓入的位址是什麼呢,調出記憶體檢視:

可以看到這兩個位址指向的是上圖所示記憶體塊,這個記憶體塊裡存的就是實現虛擬繼承的核心-偏移量**:

上圖很清晰的能看到虛擬繼承的工作原理,紅色框裡就是具體的偏移量表,而在d的物件模型中儲存了各自的偏移量**的位址。

菱形繼承 菱形虛擬繼承

菱形繼承 鑽石繼承 模型 拿如下 舉例 class person class student public person class teacher public person class graduate public student,public teacher void test 當派生類gr...

單繼承 多繼承 菱形繼承

乙個類繼承另外乙個類,那麼該類就是子類 衍生類 被繼承的這個類叫做父類 基類,超類 繼承 1 單繼承 2 多繼承 python所有的類都預設繼承父類 object 如果子類想呼叫父類私有的,要先在父類裡面定義乙個公有的,然後在公有的裡面先調出私有,最後就可以間接的調出私有,不能在子類中定義公有 cl...

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

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