20170511 請說清楚什麼是菱形繼承

2021-07-31 22:19:07 字數 1536 閱讀 6769

20170511_請說清楚什麼是菱形繼承?

1、我們都知道c++中的三大特性——「封裝、繼承、多型」,但是當我們談到「繼承」時,不免會想起乙個很重要的問題:菱形繼承。

2、那麼菱形繼承是什麼呢?請看圖。

如上圖所示,中間類a 和中間類b 共同繼承了基類base,而與此同時,派生類d 又同時繼承了a 和b。

意思就是:多個類繼承了同乙個公共基類,而這些派生類又同時被乙個類繼承。

這時,會發生什麼事情呢?請看**。

#includeusing namespace std;

class base

;class a:public base

;class b : public base

;class d :public a, public b

;int main()

這時,我們可以看到,類d的物件d 中儲存了兩份base 成員,乙份是從中間類a 繼承來的,另乙份是從中間類b 繼承來的。當我們想要呼叫從base 繼承來的fun() 函式時,就會出現編譯錯誤——呼叫不明確問題,同時這也造成了資料冗餘的問題——明明需要乙份就可以了,我們卻偏偏儲存了兩份。

3、那麼,我們該如何解決這個問題呢?

int main()

這個做法是沒有問題,但是沒有從根本上解決這個問題,而且還不方便。

如上圖所示,虛繼承,也就是讓中間類a 和中間類b 繼承基類base 時前面加上關鍵字virtual,使其成為虛繼承關係。

注意:這裡並不是d 使用虛繼承,

那麼,虛繼承是如何解決這個煩人的問題呢?請看圖。

此時,我們可以看到,中間類a 和中間類b 不再儲存基類base 中的具體內容了,而是儲存了該基類中的具體內容的乙份偏移位址,然後將基類中的資料儲存在乙個公共位置處,這樣就實現了「去除呼叫不明確問題!」

再看**:

#includeusing namespace std;

class base

;class a:virtual public base

;class b :virtual public base

;class d :public a, public b

;int main()

這樣的話,就既解決了資料冗餘的問題,又解決了直接使用d.func() 來呼叫基類base 中的func() 函式。

4、*虛繼承和虛函式是完全不同的兩個概念,

希望大家不要隨意搞混。

想要了解虛函式的同學可以看看另一篇博文《c++的繼承&多型》。

覺得清楚,跟說清楚寫清楚,兩回事

領導問吾,專案可清楚?吾很有信心的說,很清楚。後來,吾試圖把知道的東西寫出來,然後就發現說不清楚了,感覺太簡單,幾句話就說完了。可是意思表達清楚了嗎?顯然是沒有的。怎麼辦?寫下來。這下更糊塗了 這邊感覺有點糊塗,那邊感覺詞不達意。怎麼辦?跟專案有關的,想到什麼就寫什麼,然後不但的刪除增加調整,直到自...

把 rsync 錯誤報告說清楚

rsync configure 配置一 ignore errors 說明 這個選項最好加上,否則再很多crontab的時候往往發生錯誤你也未可知,因為你不可能天天去看每時每刻去看log,不加上這個出現錯誤的機率相對會很高,因為任何大點的專案和系統,磁碟io都是乙個瓶頸 rsync error 錯誤一...

把 rsync 錯誤報告說清楚

rsync configure 配置一 ignore errors 說明 這個選項最好加上,否則再很多crontab的時候往往發生錯誤你也未可知,因為你不可能天天去看每時每刻去看log,不加上這個出現錯誤的機率相對會很高,因為任何大點的專案和系統,磁碟io都是乙個瓶頸 rsync error 錯誤一...