虛基類
在前面學過的繼承過程中,不知道大家有沒有想到這種情況:在多繼承關系中,如果一個派生類的從兩個父類那里繼承過來,并且這兩個父類又恰恰是從一個基類那里繼承而來。那這樣就麻煩了,因為你可能繼承了兩份一樣的成員!
這就出現(xiàn)了所謂二義性問題,下面我們展開學習!
先給大家舉一個能說明這種多繼承的例子吧!我想來想去,想了這么一個例子:以前有一個大戶人家,起初就兩口子,男主人掌權,保管著大門鑰匙,后來他們有兩個兒子,若干年后長大成人,男主人也老了,就把鑰匙又配了兩把,分別交給他的兩個兒子,交由他們主持家業(yè),又過去好多年,兩個兒子也都成了家,又分別有一男一女,也就是家里的孫子孫女,傳宗接代。所謂人丁興旺,后來他們也長大成人,又到了交接鑰匙的時候,在古代鑰匙當然要傳給男孩,所以這個時候鑰匙當然要給孫子,此時孫子的爹和他的叔伯(也就是最初主人的倆兒子)都要配一個鑰匙給這個孫子,他手上就有了兩把。小孫子看著手里兩把鑰匙,說:“一把就夠!兩把…這不浪費嘛!”
看完這個故事,大家就好理解多繼承了,故事中最初的男主人,也就是爺爺,就是基類,他的兩個孩子,是兩個派生類,然后其中一個人的孩子,就是那個小孫子,就是最后的派生類,由于他繼承自兩個派生類。且這兩個派生類都有一個共同的成員(鑰匙,因為都繼承同一個基類——爺爺)。最后的小孫子的派生類有兩個重復的成員(鑰匙),就是二義性的根源所在!
下面,我們按照這個例子,具體寫成代碼,大家可以參考:
/************************************** //Des:C++教程demo //Author:Huang //Copyright:www.sztianhecheng.cn //Date:2017/12/18 **************************************/ #include <iostream> using namespace std; class Grandfather { public: int key; public: }; class Father1:public Grandfather { }; class Father2:public Grandfather { }; class Grandson:public Father1,public Father2 { }; int main() { Grandson A; //A.key=9; return 0; }
代碼就是剛才故事的一個表現(xiàn),為了方便形容,定義的四個類都很空,重點看繼承關系即可。即Grandson類繼承兩個father類,會有兩個key成員,這個時候如果試圖使用這個key,注意已經(jīng)聲明為public類型,在主函數(shù)中試圖賦值時候,會有“不唯一、模棱兩可”的錯誤提示,即所謂的二義性問題發(fā)生,大家可以好好體會。
那么如何規(guī)避這個問題呢?此時就要使用虛基類!所謂虛基類就是在繼承的時候在繼承類型public之前用virtual修飾一下,比如還是這個例子,只需要父親類在繼承爺爺類的時候多加一個virtual,那么這個時候,派生類和基類就只維護一份一個基類對象。避免多次拷貝,出現(xiàn)歧義。
定義方法即在兩個父親類的派生時增加virtual的聲明:
class Father1:virtual public Grandfather class Father2:virtual public Grandfather
其余不變,大家可以自行上機測試,理解二義性的產(chǎn)生及虛基類的用法。
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習題和答疑,點擊了解:
一點編程也不會寫的:零基礎C語言學練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進階課程
從零到寫出一個爬蟲的Python編程課程
只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程
信息學奧賽或C++選手的 必學C++課程
藍橋杯ACM、信息學奧賽的必學課程:算法競賽課入門課程
手把手講解近五年真題的藍橋杯輔導課程