24.C++- 抽象類(存虛函數)、接口、多重繼承
什麽是抽象類
- 用來表示現實世界中的抽象概念
- 是一種只能定義類型,而不能產生對象的類
- 只能被子類繼承,且抽象類的相關成員函數沒有完整的體現,用來被子類重寫.
比如圖形(Shape)類, 就是一個抽象的概念,因為我們無法計算這個“圖形”的面積,所以它的成員函數area()是空的。
而繼承它的子類(矩形,圓形,三角形等)就可以去重寫area()成員函數. 裏面通過數學公式,計算出面積.
參考圖形(Shape)類,代碼如下:
既然Shape是個抽象的類,那就根本沒有該類的對象,我們該如何避免他人使用Shape類創建對象呢?
答:
在C++中,通過純虛函數來避免
- 純虛函數只需要聲明函數名,不用實現函數內容.通過子類去實現
- 當類中有純虛函數時,該類就無法創建對象,因為純虛函數裏沒有具體內容,所以這個類便成為了抽象類.
- 如果子類沒有實現存虛函數,則子類也會成為抽象類
純虛函數
純虛函數需要在聲明函數名前面加上virtual,在最後面加個=0;
比如:
舉個例子
比如我們的藍牙,可以打開,關閉,收發數據
而網卡也一樣,可以打開,關閉,收發數據.
類似的還有串口等等
這些類都擁有同樣的行為,只是內容不同,所以它們的父類Channel只需要構造純虛函數,所以便被稱為接口,該父類代碼如下:
多重繼承的問題1
當多個不同的父類指針指向同一個多重繼承的子類時,可能擁有不同地址
比如:
運行打印:
為什麽,pa指針和pb指針都指向d對象,它們的地址卻有所不同?
這是因為Derived d對象地址裏依次存了兩個不同的父類成員變量值,如下圖所示:
從上圖看到,其實pa和pb還是位於d對象地址裏,只是指向的位置不同而已.雅思培訓教材所以在多重繼承裏,最好不要使用等號直接判斷兩個指針對象是否相等.
多重繼承的問題2
多重繼承可能產生冗余的成員
比如:
老師teacher類,學生student類都繼承於people類
而有些老師,為了工作還要考博士學位,既是老師又是學生,所以同時繼承於老師teacher類,學生student類,則該類的成員便會擁有兩個people類成員,從而產生冗余
在工程中,如何正確使用多重繼承
- 只繼承一個父類和多個接口
- 由於接口只有存虛函數,從而避免了冗余的成員
- 在父類中提供equal()成員函數,
- 通過equal()成員函數來判斷指針是否指向當前對象,使用dynamic_cast強制轉換
例如:
運行打印:
可以發現,使用dynamic_cast轉換,判斷出來的地址就是相等的.
以p->equal(dynamic_cast<Base*>(pInt1))為例,我們編譯時,編譯器就會去檢查pInt1所在的地址,然後找到是d對象,通過d對象找到Base父類,從而去修正pInt1指針的地址.
文章來源:https://www.cnblogs.com/lifexy/p/8743963.html
24.C++- 抽象類(存虛函數)、接口、多重繼承