- N +

封裝繼承多態(tài)的理解?封裝 多態(tài) 繼承 三大特性

類的繼承和多態(tài)的定義

多態(tài):同一操作作用于不同的對象,可以有不同的解釋,產(chǎn)生不同的執(zhí)行結(jié)果。在運行時,可以通過指向基類的指針,來調(diào)用實現(xiàn)派生類中的方法。多態(tài)就是允許方法重名參數(shù)或返回值可以是父類型傳入或返回。

繼承的概念:繼承是面向?qū)ο笞铒@著的一個特性。繼承是從已有的類中派生出新的類,新的類能吸收已有類的數(shù)據(jù)屬性和行為,并能擴展新的能力。

c++是如何實現(xiàn)多繼承帶來的多態(tài)問題

多態(tài)是指同樣的消息被不同類型的對象接收時導致完全不同的的行為。有虛函數(shù)的類才能叫多態(tài)類型的類,可以從探索虛函數(shù)是如何實現(xiàn)動態(tài)綁定的來了解如何實現(xiàn)多繼承中的多態(tài)。

單繼承時虛函數(shù)動態(tài)綁定的實現(xiàn)原理

每個類各有一個虛表(虛函數(shù)表),虛表的內(nèi)容是由編譯器安排的。c++語言并沒有規(guī)定虛函數(shù)表的內(nèi)容。派生類的虛表中,基類聲明的虛函數(shù)對應的指針放在前面,派生類新增的虛函數(shù)的對應指針放在后面,這樣一個虛函數(shù)的指針在基類虛表和派生類虛表中具有相同的位置。每個多態(tài)類型的對象中都有一個指向當前類型的虛表的指針,該指針在構(gòu)造函數(shù)中被賦值。當通過基類的指針或引用調(diào)用一個虛函數(shù)時,就可以通過虛表指針找到該對象的虛表,進而找到存放該虛函數(shù)的指針的虛表條目。將該條目中存放的指針讀出后,就可獲得應當被調(diào)用的函數(shù)的入口地址,然后調(diào)用該虛函數(shù),虛函數(shù)的動態(tài)綁定就是這樣完成的。

如下圖所示:

由上圖可以看到基類Base有f(),g()函數(shù),派生類還有新增的h()函數(shù),那么這種單繼承的虛函數(shù)實現(xiàn)動態(tài)綁定的方式是這樣的:

從這張超大圖片可以看到,每個Base對象都有一個指向Base的虛表的指針,虛表存放著指向每個函數(shù)的指針,這些指針存放著對應函數(shù)的地址,這樣通過虛表指針就能找到虛表,通過虛表就能找到函數(shù)指針,通過函數(shù)指針就能找到函數(shù),這樣虛函數(shù)的動態(tài)綁定就完成了。派生類Base2也一樣。

溫馨提示:執(zhí)行一個類的構(gòu)造函數(shù)時,首先被執(zhí)行的是基類的構(gòu)造函數(shù),因此構(gòu)造一個派生類的對象時,該對象的虛表指針首先會被指向基類的虛表。只有當基類構(gòu)造函數(shù)執(zhí)行完后,虛表指針才會被指向派生類的虛表,這就是基類構(gòu)造函數(shù)調(diào)用虛函數(shù)時不會調(diào)用派生類的虛函數(shù)的原因。

在多繼承時,情況會變得更加復雜,因為在多繼承時,情況會更加復雜,因為每個基類都有各自的虛函數(shù),這樣繼承了多個基類的派生類需要多個虛表(或一個虛表分為多段,每個基類的虛表指針指向其中一段的地址。因為有些編譯器把多個虛表連成一個)如圖所示:

派生類Base3公有繼承了Base,Base2,那么虛函數(shù)動態(tài)綁定的實現(xiàn)方式是這樣的:

提示:多重繼承時,派生類新增的成員放在第一個表,比如上圖Base3()的虛表的m()指針。

事實上,一個類的虛表中存放的不只是虛函數(shù)的指針,用于支持運行時類型識別的對象的運行時類型信息也需要通過虛表來訪問,只有多態(tài)類型有虛表,因此只有多態(tài)類型支持運行時類型識別。

以上就是我的回答,有不同意見的歡迎來討論,喜歡我的回答請關(guān)注,我們一起學習。

返回列表
上一篇:
下一篇: