柚子快報(bào)邀請(qǐng)碼778899分享:C++:虛函數(shù)與多態(tài)
柚子快報(bào)邀請(qǐng)碼778899分享:C++:虛函數(shù)與多態(tài)
一、虛函數(shù)和多態(tài)
(1)虛函數(shù):
在類的定義中,前面有virtual關(guān)鍵字的成員函數(shù)就是虛函數(shù)
注意:virtual關(guān)鍵字只出現(xiàn)在類定義的函數(shù)聲明中,寫函數(shù)體時(shí)不用
(2)多態(tài)
Ⅰ.多態(tài)的表現(xiàn)形式:
1.指針
上面提到,派生類的對(duì)象可以賦給基類指針,那么當(dāng)我們用這個(gè)指針調(diào)用一個(gè)基類和派生類中同名同參的虛函數(shù)時(shí):
①若該指針指向的是一個(gè)基類的對(duì)象,那么被調(diào)用的會(huì)是基類的虛函數(shù)
②若該對(duì)象指向的是一個(gè)派生類的對(duì)象,那么被調(diào)用的會(huì)是派生類的虛函數(shù)
??????????????????????????????????????
2.引用
上面提到,派生類的對(duì)象可以賦給基類引用,那么當(dāng)我們用這個(gè)引用調(diào)用一個(gè)基類和派生類中同名同參的虛函數(shù)時(shí):
①若該引用的對(duì)象是一個(gè)基類的對(duì)象,那么被調(diào)用的會(huì)是基類的虛函數(shù)
②若該引用的對(duì)象是一個(gè)派生類的對(duì)象,那么被調(diào)用的會(huì)是派生類的虛函數(shù)
?????????????????????????????????????????????
Ⅱ.多態(tài)的作用
??在面向?qū)ο蟮某绦蛟O(shè)計(jì)中使用多態(tài),能夠增強(qiáng)程序的可擴(kuò)充性,即程序需要修改或增加功能的時(shí)候,需要改動(dòng)和增加的代碼較少。
??實(shí)戰(zhàn)案例:北京大學(xué)程序設(shè)計(jì)魔獸世界大作業(yè)
注意事項(xiàng):
1.在非構(gòu)造函數(shù),非析構(gòu)函數(shù)的成員函數(shù)中調(diào)用虛函數(shù),是多態(tài)!(因?yàn)樵诰幾g時(shí)并不會(huì)考慮構(gòu)造函數(shù)和析構(gòu)函數(shù)之外的函數(shù)調(diào)用)
2.在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù),不是多態(tài)。編譯時(shí)即可確定,調(diào)用的函數(shù)是自己的類或基類中定義的函數(shù),不會(huì)等到運(yùn)行時(shí)才決定調(diào)用自己的還是派生類的函數(shù)。
3.派生類中和基類中虛函數(shù)同名同參數(shù)表的函數(shù),不加virtual也自動(dòng)成為虛函數(shù)
總的來說:“多態(tài)”的關(guān)鍵在于通過基類指針或引用調(diào)用一個(gè)虛函數(shù)時(shí),編譯時(shí)不確定到底調(diào)用的是基類還是派生類的函數(shù),運(yùn)行時(shí)才確定究竟調(diào)用哪個(gè)類下的函數(shù),這種機(jī)制被叫做“動(dòng)態(tài)聯(lián)編”。
二、多態(tài)的實(shí)現(xiàn)原理
我們先來觀察兩個(gè)唯一區(qū)別在是否包含了虛函數(shù)的類的大小
?????????????????????????????????????????????????????????????????????????????????????????????????????????
發(fā)現(xiàn)含有虛函數(shù)的Base2會(huì)比不含虛函數(shù)的Base1多出8個(gè)字節(jié)
每一個(gè)有虛函數(shù)的類(或有虛函數(shù)的類的派生類)都有一個(gè)虛函數(shù)表,該類的任何對(duì)象中都放著虛函數(shù)表的指針。虛函數(shù)表中列出了該類的虛函數(shù)地址,多出來字節(jié)就是用來存放虛函數(shù)表的地址的。具體構(gòu)造如下:
多態(tài)的函數(shù)調(diào)用語句被編譯成一系列根據(jù)基類指針?biāo)赶虻模ɑ蚧愐盟玫模?duì)象中存放的虛函數(shù)表的地址,在虛函數(shù)表中查找虛函數(shù)地址,并調(diào)用虛函數(shù)的指令。
三、虛析構(gòu)函數(shù)
通過基類的指針刪除派生類對(duì)象時(shí),通常情況下只會(huì)調(diào)用基類的析構(gòu)函數(shù)。
????????????????????????????????????????????????????????????
但是當(dāng)我們刪除一個(gè)派生類的對(duì)象時(shí),應(yīng)該先調(diào)用派生類的析構(gòu)函數(shù),然后調(diào)用基類的析構(gòu)函數(shù)。
這個(gè)時(shí)候我們就要人為地把基類的析構(gòu)函數(shù)聲明為virtual(派生類的析構(gòu)函數(shù)可以不聲明virtual),然后我們通過基類的指針刪除派生類對(duì)象時(shí),就會(huì)先調(diào)用派生類的析構(gòu)函數(shù)再調(diào)用基類的析構(gòu)函數(shù)。
????????????????????????????????????????????????????????????
四、純虛函數(shù)和抽象類
(1)純虛函數(shù):帶有純說明符=0的虛函數(shù),目的是為純虛函數(shù)提供定義(若純虛函數(shù)是析構(gòu)函數(shù)那么必須提供定義).
?注意:此定義必須要類體內(nèi)部提供(函數(shù)聲明的語法不允許純說明符=0與函數(shù)體一起出現(xiàn))
2.抽象類:包含純虛函數(shù)的類叫做抽象類
注意:
①抽象類只能作為基類來派生新類使用,不能創(chuàng)建抽象類的對(duì)象
②抽象類的指針和引用可以指向由抽象類派生出來的類的對(duì)象
③在抽象類的成員函數(shù)內(nèi)可以調(diào)用純虛函數(shù),但是在構(gòu)造函數(shù)或析構(gòu)函數(shù)內(nèi)部不能調(diào)用純虛函數(shù)。
④如果一個(gè)類從抽象類派生而來,那么當(dāng)且僅當(dāng)它實(shí)現(xiàn)了基類中的所有純虛函數(shù),它才能成為非抽象類。
柚子快報(bào)邀請(qǐng)碼778899分享:C++:虛函數(shù)與多態(tài)
文章來源
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。