????????????????????????????????????????食用指南:本文在有C++基礎的情況下食用更佳??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?🍀本文前置知識:C++虛函數(很重要,內部剖析)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ??今日夜電波:僕らのつづき—柊優花
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1:06?━━━━━━?💟──────── 3:51
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????🔄 ? ?? ? ? ? ?? ? ???
??????????????????????????????????????💗關注👍點贊🙌收藏您的每一次鼓勵都是對我莫大的支持😍?
目錄
🌸一、虛繼承的引入—菱形繼承
什么是菱形繼承?
?????????🌰
? ? ? ? 內層結構?
?💮二、什么是虛繼承?
????????語法定義
? ? ? ??🌰
????????內層結構
🌺三、使用虛繼承的原因
🌼四、使用虛繼承需注意
🌸一、虛繼承的引入—菱形繼承
????????什么是菱形繼承?
????????菱形繼承是指在繼承關系中存在一個派生類同時繼承自兩個或多個基類,而這些基類又共同繼承自同一個基類。這樣就會導致派生類中存在多個相同的基類子對象,從而造成資源浪費和二義性問題。
?????????🌰
class Animal{public:int data;};class Sheep :public Animal{public:};class Tuo :public Animal{public:};class SheepTuo :public Sheep, public Tuo{public:};int main(int argc, char* argv[]){SheepTuo st;//SheepTuo 從Sheep中繼承data 從Tuo繼承data 就產生二義性//st.data = 200;//err//第一種方式:加作用域解決st.Sheep::data = 200;st.Tuo::data = 300;return 0;}
? ? ? ? 內層結構?
????????這段代碼的內層結構如下:? ? ? ??
????????這就是典型的菱形繼承的例子,SheepTuo 從Sheep中繼承data 從Tuo繼承data 就產生二義性。但是我們可以采用加作用域的方式解決問題。
? ? ? ? 那有沒有更加優的解決辦法呢?答案是虛繼承!?
?💮二、什么是虛繼承?
? ? ? ?本文為虛函數后的知識, 強烈建議各位先去了解一下此文:
? ? ? ? ? ? ??????????? ?🍀本文前置知識:C++虛函數(很重要,內部剖析)
????????在多繼承中,如果一個派生類從兩個或多個基類繼承,而這些基類又共同繼承自同一個基類,那么就會出現菱形繼承問題。這種情況下,派生類將會有兩份相同的基類成員,導致二義性和冗余。
????????虛繼承通過在派生類對共同基類的繼承前加上關鍵字"virtual"來解決這個問題。使用虛繼承后,共同基類的成員只會在派生類中存在一份,從而避免了二義性和冗余。
????????通過使用虛繼承,可以確保多繼承中的共同基類只會在派生類中存在一份,從而解決菱形繼承問題。
????????語法定義
class Base {};class Derived : virtual public Base {};
? ? ? ??🌰
class Animal{public:int data;};class Sheep :virtual public Animal{public:};class Tuo :virtual public Animal{public:};class SheepTuo :public Sheep, public Tuo{public:};int main(int argc, char* argv[]){SheepTuo st;//在加入virtual后二義性以及冗余得以解決st.data = 200;return 0;}
????????內層結構
????????這段代碼的內層結構如下:?
? ? ? ? ? Animal:(未變,因為改變的不是他)
?????????Sheep:(產生了虛基指針和虛基表)
?????????Tuo:(同樣也產生了虛基指針和虛基表)
? ? ? ? ?SheepTuo:(保存了兩個父類的虛基指針)
🌺三、使用虛繼承的原因
????????敏銳的你可能已經發現了,每當使用了virtual以使用虛繼承后,相對于沒有使用虛繼承的子類,他們的的內存都加了4字節的vptr指針,而最后的最后的那個子類則是多出了兩個4字節的vptr指針,很明顯,通過內層結構圖我們得知,這兩個指針分別指向這個子類的兩個父類的虛基表vftable。之所以 產生 vbptr和vbtable目的 是為了保證 不管多少個繼承 虛基類的數據只有一份。
? ? ? ? ?一圖讓你明白~
🌼四、使用虛繼承需注意
????????虛繼承只有在多繼承時才有用。虛繼承只能解決具備公共祖先的多繼承所帶來的二義性問題,不能解決沒有公共祖先的多繼承的。單繼承以及只有一層的繼承都是不行的。
????????虛繼承:不管繼承多少次 虛基類 只有一份。
????????????????感謝你耐心的看到這里?( ′・?・` )比心,如有哪里有錯誤請踢一腳作者o(╥﹏╥)o!??
?????????????????????????????????
?????????????????????????????????????????????????????????????????給個三連再走嘛~??????
?