虛繼承 是物件導向程式設計中的一種技術,是指乙個指定的基類,在繼承體系結構中,將其成員資料例項共享給也從這個基型別直接或間接派生的其它類。形式:
在繼承定義中包含了virtual關鍵字的繼承關係,如下圖中,類a就叫做虛基類。
虛擬繼承是多重繼承中的菱形繼承所特有的概念。虛擬基類是為解決多重繼承而出現的。
菱形繼承中既有多繼承,如下圖所示:
菱形繼承中也有多重繼承:
現實中的例子:
問題來了:在類d的例項中將有兩份類a的變數,這種資料冗餘的現象我們不能容忍其存在?這就會需要用到虛繼承!!!廢話不多說直接上**,直接貼上可用。
#include
#include
#include
using namespace std;
/*** 定義人類: person
*/class person
~person()
void eat()
protected:
string m_strcolor;
};/**
* 定義工人類: worker
* 虛繼承人類
*/class worker : virtual public person
~worker()
void work()
protected:
string m_strname;
};/**
* 定義兒童類:children
* 虛繼承人類
*/class children : virtual public person
~children()
void play()
protected:
int m_iage;
};/**
* 定義童工類:childlabourer
* 公有繼承工人類和兒童類
*/class childlabourer:public children,public worker
~childlabourer()
};int main(void)
輸出:
person如果不加virtual關鍵字時候的輸出:children
worker
childlabourer
blue
person -- eat
blue
person -- eat
qqwork
0x60314814
play
~childlabourer
~worker
~children
~person
person分析:children
person
worker
childlabourer
workeryellow
person -- eat
childrenyellow
person -- eat
qqwork
0x60310814
play
~childlabourer
~worker
~person
~children
~person
(1)不加virtual情況:
不加virtual,也就是不是虛繼承的情況下,在例項化童工這個類的時候,會按繼承順序,先呼叫類children的建構函式再呼叫類worker的建構函式,最後呼叫自己的建構函式,而呼叫children和worker的建構函式的時候又會分別先呼叫它們的基類person的建構函式,這樣就會生成兩個person的物件,從而生成兩份person所含有的資料成員,即童工類childlabourer在例項化的時會生成在記憶體中會生成兩份person的資料成員,所以在呼叫children和worker的eat()函式的時候,會分別列印出workeryellow和childrenyellow,(這裡注意children和worker裡面的eat()都是從person繼承來的,因此分別都會列印出person --eat;還要注意呼叫方式:p->worker::eat();p->children::eat())
銷毀物件時,會先呼叫自己的析構函式,再呼叫兩個基類的析構函式,兩個基類的析構函式呼叫之前都會先呼叫person的析構函式。呼叫析構函式的順序和呼叫建構函式相反。
(2)加virtual的情況:
加virtual以後,從輸出結果可以看出,在例項化童工類childrenlabourer時,建構函式的呼叫順序比較正常,只呼叫了一次person,析構函式的呼叫也只會呼叫一次person的析構函式,這說明例項化童工類時只會生成乙份person的物件,表明了在物件的記憶體空間中僅僅能夠包含乙份虛基類的物件,而且列印的結果都是blue,即childrenlabourer的資料不會再傳入虛基類person。這就講資料冗餘的問題解決了。
C 學習之繼承篇(多繼承與多重繼承)
1.多繼承 多繼承是指乙個子類繼承多個父類。多繼承對父類的個數沒有限制,繼承方式可以是公共繼承 保護繼承和私有繼承,不寫繼承方式,預設是private繼承 多繼承舉例 include include include using namespace std 定義工人類 worker 資料成員 m st...
C 學習之繼承篇(多繼承與多重繼承)
1.多繼承 多繼承是指乙個子類繼承多個父類。多繼承對父類的個數沒有限制,繼承方式可以是公共繼承 保護繼承和私有繼承,不寫繼承方式,預設是private繼承 多繼承舉例 include include include using namespace std 定義工人類 worker 資料成員 m st...
c 之虛繼承 多重繼承的問題
什麼是多重繼承 如圖 什麼是多繼承 如圖 繼承中的特殊結構 菱形繼承結構帶來的問題,d會有兩個a中的資料成員 class a class b public a class c public a class d public b,public c d中會有兩個a乙個是從b繼承的,乙個是從c繼承的 出現...