當我們談c++時,我們談些什麼?
封裝,繼承,多型。這是c++語言的三大特性,而每次在談到繼承時我們不可避免的要談到乙個很重要的問題——菱形繼承。
a.菱形繼承是什麼
如上圖,菱形繼承即多個類繼承了同乙個公共基類,而這些派生類又同時被乙個類繼承。這麼做會引發什麼問題呢,讓我們來看一段**吧
我們可以看見d的物件模型裡面儲存了兩份base,當我們想要呼叫我們從base裡繼承的fun時就會出現呼叫不明確問題,並且會造成資料冗餘的問題,明明可以只要乙份就好,而我們卻儲存了兩份。#includeusing namespace std;
class base
};
class a:public base
;
class b : public base
; class d :public a, public b
; int main()
[cpp] view plain copy
#includeusing namespace std;
class base
};
class a:public base
;
class b : public base
; class d :public a, public b
; int main()
那麼我們可以怎樣解決呢?
第一種解決方法,使用域限定我們所需訪問的函式
這樣的做法是沒有問題的,但是,這樣做非常的不方便,並且當程式十分大的時候會造成我們思維混亂int main()
[cpp] view plain copy
int main()
於是,c++給了我們乙個別的解決方案——虛繼承
b.虛繼承
虛繼承是什麼?
如上圖,虛繼承即讓a和b在繼承base時加上virtural關鍵字,這裡需要記住不是d使用虛繼承
那麼,虛繼承又是怎麼解決這些煩人的問題的呢?
我們可看見在a和b中不再儲存base中的內容,儲存了乙份
偏移位址
,然後將base的資料儲存在乙個公共位置處這樣保證了資料冗餘性的降低同時,我們也能直接的使用d.fun()來呼叫base裡的fun函式。
*虛繼承和虛函式是完全不同的兩個概念,希望大家不要隨意搞混,想要了解虛函式的同學可以看看博主的另一篇博文《c++的繼承&多型》#includeusing namespace std;
class base
};
class a:virtual public base
;
class b :virtual public base
; class d :public a, public b
; int main()
[cpp] view plain copy
#includeusing namespace std;
class base
};
class a:virtual public base
;
class b :virtual public base
; class d :public a, public b
; int main()
派生類物件模型之菱形繼承派生類物件模型
當繼承關係超過兩重後,就不可避免地出現菱形繼承的問題,什麼是菱形繼承呢?我們來看乙個圖 像這樣,類b1 b2繼承自類a,而類c又與類b1 b2是多繼承的關係,整個繼承關係呈菱形,這就是菱形繼承。那麼菱形繼承存在什麼問題呢?先給出這樣乙個繼承關係 class a int a class base1 p...
探索c 的物件模型(二) 菱形繼承的多型模型
首先我們已經知道了多繼承和單繼承的物件模型 接下來我們來看乙個複雜的菱形繼承 菱形繼承的多型繼承 然偶我們再將虛表打出來看一看這兩個虛表指標的裡儲存的虛函式各是什麼 我們可以明顯的看到,b裡的虛表和c裡的虛表此時都被d繼承了之後進行了虛函式的重寫,因為d繼承了b和c所以都被d重寫了虛函式此時就打出來...
c 之菱形繼承問題
昨天面試問了菱形繼承的問題,回答的稀巴爛,回來趕快好好學習一波!菱形繼承如下圖 可以看到,如果不利用域限定需要訪問的函式,那麼就會出現模糊呼叫的問題,但是貌似c 給了更好的方法,虛繼承!includeusing namespace std class base class a virtual pub...