網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
C++支持多繼承,即允許一個(gè)類(lèi)同時(shí)繼承多個(gè)類(lèi)。
關(guān)于多繼承,一直以來(lái)爭(zhēng)議不斷,有一部分人認(rèn)為多繼承會(huì)帶來(lái)大量的問(wèn)題,為了解決這些問(wèn)題會(huì)使得語(yǔ)言本身變得非常復(fù)雜,因此應(yīng)當(dāng)避免。另外一派認(rèn)為多繼承在某些場(chǎng)景下可以起到非常關(guān)鍵的作用,應(yīng)當(dāng)予以支持。
關(guān)于多重繼承是好是壞,這是一個(gè)非常復(fù)雜的問(wèn)題,網(wǎng)上歷來(lái)爭(zhēng)議不斷。因此不過(guò)多闡述,感興趣的同學(xué)可以查閱一下相關(guān)資料。僅僅從實(shí)際支持來(lái)看,目前市面上大部分的語(yǔ)言包括Java僅支持單繼承,只有C++等少數(shù)語(yǔ)言支持多繼承。這和C++的理念也有關(guān),即認(rèn)定不能通過(guò)減少語(yǔ)言特性來(lái)增強(qiáng)語(yǔ)言的表達(dá)力。
看完?duì)幾h之后,我們來(lái)看看究竟什么是多繼承呢?
我們來(lái)看一段代碼案例:
class A{ public: ? ? void funcA(); }; class B{ private: ? ? bool funcB() const; }; class C: public A, public B{ ... };
在這段代碼當(dāng)中我們定義了兩個(gè)類(lèi)A和B,然后我們創(chuàng)建了一個(gè)類(lèi)C,同時(shí)繼承了A和B。這就是多繼承,這里要注意一點(diǎn),我們必須用關(guān)鍵字public
來(lái)限定每一個(gè)基類(lèi),否則的話編譯器會(huì)默認(rèn)這是一個(gè)私有繼承。
如果我們稍微修改一下代碼,就會(huì)出現(xiàn)一些問(wèn)題,比如:
class A{ public: ? ? void func(); }; class B{ private: ? ? bool func() const; }; class C: public A, public B{ ... };
在上面這個(gè)例子當(dāng)中A和B都包含了函數(shù)func
,在下面的執(zhí)行語(yǔ)句當(dāng)中會(huì)報(bào)錯(cuò)。
C c; c.func();
雖然B中的func
函數(shù)是私有的,但對(duì)于編譯器來(lái)說(shuō)依然是有歧義的。如果想要消除歧義,我們可以這樣調(diào)用c.A::func()。
當(dāng)多繼承的父類(lèi)擁有更高的繼承層級(jí)的時(shí)候,可能會(huì)出現(xiàn)更復(fù)雜的問(wèn)題,比如多繼承菱形。也就是多個(gè)類(lèi)之間的繼承關(guān)系構(gòu)成了一個(gè)抽象意義上的菱形,
比如我們參考一下C++ Primer中的例子:
在上面這張圖當(dāng)中,Singer
和Waiter
都繼承了Worker,而SingingWaiter
同時(shí)繼承了Singer和Waiter。從圖上來(lái)看,這似乎沒(méi)什么問(wèn)題,但在實(shí)現(xiàn)上問(wèn)題不少。
比如說(shuō),對(duì)于SingingWaiter
類(lèi)來(lái)說(shuō),它當(dāng)中包含了多少Worker呢?
答案是有兩個(gè),從Singer這邊繼承了一個(gè)Worker,從Waiter又繼承了一個(gè)Worker。
那么我們這樣寫(xiě)就會(huì)出現(xiàn)問(wèn)題:
SingingWaiter sw; Worker *p = &sw;
通常這種賦值的時(shí)候,會(huì)將基類(lèi)指針設(shè)置成派生類(lèi)中基類(lèi)對(duì)象的地址,但由于sw對(duì)象當(dāng)中包含兩個(gè)Worker對(duì)象,有兩個(gè)地址,所以也會(huì)導(dǎo)致歧義。
我們可以使用強(qiáng)制轉(zhuǎn)換的方式消除歧義:
SingingWaiter sw; Worker *p = (Singer*) &sw; Worker *p = (Waiter*) &sw;
但顯然這樣的方法雖然能夠解決問(wèn)題,
原文鏈接:https://mp.weixin.qq.com/s/2fD5I3GwLnDDy_dwTv15aA
相關(guān)推薦
- 2022-04-14 解決 zsh:command not found
- 2022-10-25 Python條件語(yǔ)句的使用_python
- 2022-08-22 如何使用Python?Matplotlib繪制條形圖_python
- 2024-03-20 redis閃退的三大解決辦法(windows版本)
- 2022-06-01 詳解Pandas中stack()和unstack()的使用技巧_python
- 2022-12-09 C++輸出問(wèn)題:保留兩位小數(shù)_C 語(yǔ)言
- 2022-03-19 Nginx純配置實(shí)現(xiàn)日志實(shí)時(shí)上報(bào)的思路與方法_nginx
- 2023-03-29 C++中字符串全排列算法及next_permutation原理詳解_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支