本文主要介紹C++中虛繼承的相關(guān)內(nèi)容
I闸与、菱形繼承
要了解C++的虛繼承锥债,首先要先了解菱形繼承的概念及其帶來(lái)的危害。
1旗吁、菱形繼承是指一個(gè)派生來(lái)通過(guò)不同的繼承途徑踩萎,繼承了同一個(gè)基類的內(nèi)容,如下圖所示:
2很钓、上圖中的繼承關(guān)系會(huì)造成兩個(gè)方面的影響香府,一是派生類D會(huì)存在兩份基類A中的拷貝,這樣會(huì)造成內(nèi)存的浪費(fèi)码倦,而是在發(fā)生動(dòng)態(tài)綁定時(shí)企孩,會(huì)存在虛函數(shù)調(diào)用的二義性。
II袁稽、虛繼承
1勿璃、虛繼承就是為了解決上述的兩個(gè)問(wèn)題,虛繼承的機(jī)構(gòu)如下圖所示:
2运提、虛繼承的底層實(shí)現(xiàn) :
虛繼承一般通過(guò)虛基類指針和虛基類表實(shí)現(xiàn)蝗柔,每個(gè)虛繼承的子類都有一個(gè)虛基類指針和虛基類表(由虛基類指針指向)。
虛基類表中記錄了虛基類與本類的偏移地址民泵;通過(guò)偏移地址癣丧,就找到了虛基類成員,而虛繼承也不用像普通多重繼承一樣需要維護(hù)兩份拷貝栈妆,這樣節(jié)省了存儲(chǔ)空間胁编。
3、上述描述解決了菱形繼承中的浪費(fèi)內(nèi)存空間的問(wèn)題鳞尔,但還未解決二義性問(wèn)題嬉橙,在虛繼承中,如果B和C都重寫了A中的虛函數(shù)a()寥假,則D必須重寫虛函數(shù)a()市框,否則會(huì)出現(xiàn)二義性問(wèn)題。
詳細(xì)內(nèi)容可以參考探索多態(tài)模型—菱形繼承和菱形虛擬繼承一文糕韧。