-
virtual 不能修飾普通函數(shù)
virtual不能修飾靜態(tài)成員函數(shù)
virtual不能修飾內(nèi)聯(lián)函數(shù)(會(huì)忽略掉inline而成為虛函數(shù))
構(gòu)造函數(shù)不能為虛函數(shù)
查看全部 -
當(dāng)父類(lèi)定義一個(gè)虛函數(shù)時(shí),隨即創(chuàng)建了一個(gè)虛函數(shù)表指針
查看全部 -
靜態(tài)綁定(早綁定):在編譯階段已經(jīng)確定使用哪一個(gè)函數(shù)
動(dòng)態(tài)多態(tài)(晚綁定):以封裝和繼承為基礎(chǔ),用虛函數(shù)實(shí)現(xiàn)
查看全部 -
純虛函數(shù)不能實(shí)例化對(duì)象,但可以指向子類(lèi)地址!!!
查看全部 -
我們可以為純虛函數(shù)提供定義,不過(guò)函數(shù)體必須定義在類(lèi)的外部。若定義在類(lèi)的內(nèi)部,會(huì)出現(xiàn)錯(cuò)誤
查看全部 -
VIRTUAL只需要加在父類(lèi)里邊(析構(gòu)函數(shù)和同名成員函數(shù))就好,析構(gòu)函數(shù)前邊加是為了防止沒(méi)有釋放子類(lèi)對(duì)象的內(nèi)存導(dǎo)致內(nèi)存泄露,同名成員函數(shù)前加是為了父類(lèi)實(shí)例化的對(duì)象指針能夠指向子類(lèi)數(shù)據(jù)成員。
如果我們沒(méi)有在子類(lèi)當(dāng)中定義同名的虛函數(shù),那么在子類(lèi)虛函數(shù)表中就會(huì)寫(xiě)上父類(lèi)的虛函數(shù)的函數(shù)入口地址;如果我們?cè)谧宇?lèi)當(dāng)中也定義了虛函數(shù),那么在子類(lèi)的虛函數(shù)表中我們就會(huì)把原來(lái)的父類(lèi)的虛函數(shù)的函數(shù)地址覆蓋一下,覆蓋成子類(lèi)的虛函數(shù)的函數(shù)地址,這種情況就稱(chēng)之為函數(shù)的覆蓋。
查看全部 -
虛函數(shù)實(shí)現(xiàn)多態(tài)的原理:
虛函數(shù)表指針(指向了虛函數(shù)表的首地址)->虛函數(shù)表(地址的偏移找到對(duì)應(yīng)的虛函數(shù)的地址)->虛函數(shù)。
在父類(lèi)指針指向子類(lèi)實(shí)例時(shí):
? 如果子類(lèi)中沒(méi)有定義相同名稱(chēng)的虛函數(shù),就會(huì)從從父類(lèi)中繼承了,所以在實(shí)例化時(shí)會(huì)產(chǎn)生一個(gè)虛函數(shù)表(跟父類(lèi)中的不是同一個(gè),即虛函數(shù)表指針不同),但是相應(yīng)函數(shù)(比如計(jì)算面積)的函數(shù)指針是一樣的(同樣的入口地址)。
? 如果在子類(lèi)中定義了同名的虛函數(shù),就會(huì)在子類(lèi)的虛函數(shù)列表中將父類(lèi)中定義的虛函數(shù)的函數(shù)地址覆蓋掉,從而實(shí)現(xiàn)多態(tài)。
【虛析構(gòu)函數(shù)的原理】:通過(guò)父類(lèi)類(lèi)指針指向子類(lèi)實(shí)例的內(nèi)存空間,找到子類(lèi)的虛函數(shù)表指針?biāo)赶虻奶摵瘮?shù)表,然后在表中找到虛析構(gòu)函數(shù)地址,從而找到虛析構(gòu)函數(shù)執(zhí)行子類(lèi)的虛析構(gòu)函數(shù),再自動(dòng)執(zhí)行父類(lèi)的虛析構(gòu)函數(shù)。
補(bǔ)充1:理論前提,執(zhí)行完子類(lèi)的析構(gòu)函數(shù)后,會(huì)執(zhí)行父類(lèi)的析構(gòu)函數(shù)。
補(bǔ)充2:C++中的虛函數(shù)的作用主要是實(shí)現(xiàn)了多態(tài)的機(jī)制。關(guān)于多態(tài),簡(jiǎn)而言之就是用父類(lèi)型別的指針指向其子類(lèi)的實(shí)例,然后通過(guò)父類(lèi)的指針調(diào)用實(shí)際子類(lèi)的成員函數(shù)。
這種技術(shù)可以讓父類(lèi)的指針有“多種形態(tài)”,這是一種泛型技術(shù)。所謂泛型技術(shù),說(shuō)白了就是試圖使用不變的代碼來(lái)實(shí)現(xiàn)可變的算法。
?比如:模板技術(shù),RTTI技術(shù),虛函數(shù)技術(shù),要么是試圖做到在編譯時(shí)決議,要么試圖做到運(yùn)行時(shí)決議。
查看全部 -
虛函數(shù)特性可以被繼承,當(dāng)子類(lèi)中定義的函數(shù)與父類(lèi)中虛函數(shù)的聲明相同時(shí),該函數(shù)也是虛函數(shù)。只是平時(shí)我們都習(xí)慣在子類(lèi)的虛函數(shù)前面也加上virtual關(guān)鍵字。
查看全部 -
并不是所有的都加上virtual就完事了。
1、使用virtual會(huì)產(chǎn)生一個(gè)虛擬指針表,要維持這個(gè)表,便額外加大了系統(tǒng)的開(kāi)銷(xiāo)。
2、也不是所有的成員函數(shù)都需要實(shí)現(xiàn)多態(tài)的,總有些函數(shù)實(shí)現(xiàn)的功能意義時(shí)固定的,比如說(shuō)加減乘除
3、虛繼承無(wú)非是為了避免諸如菱形繼承的情況,在我們構(gòu)建類(lèi)圖的時(shí)候,就需要考慮到這些問(wèn)題,如果能不用虛繼承,就不用咯。
綜上,應(yīng)該是能不用就不用,C++就是以號(hào)稱(chēng)節(jié)省資源,運(yùn)行效率高的。如果在寫(xiě)程序的時(shí)候,使得消耗過(guò)多的系統(tǒng)資源,便失去了這門(mén)語(yǔ)言高效的意義了。那還不如直接用一些新興的語(yǔ)言如GO,SCALA之類(lèi)的了。
查看全部 -
Shape 類(lèi)的析構(gòu)函數(shù)前 如果沒(méi)加virtual,則只會(huì)執(zhí)行父類(lèi)的 析構(gòu)函數(shù),如果加了 virtual,則先執(zhí)行子類(lèi)的析構(gòu)函數(shù),在執(zhí)行父類(lèi)的析構(gòu)函數(shù)。
如果加了 virtual 父類(lèi)就會(huì)通過(guò)虛函數(shù)表 和虛函數(shù)表指針 找到子類(lèi)的析構(gòu)函數(shù) 從而釋放掉子類(lèi)對(duì)象。
查看全部 -
虛函數(shù)=0就是純虛函數(shù)
含有純虛函數(shù)的類(lèi)叫做抽象類(lèi)
抽象類(lèi)無(wú)法實(shí)例化對(duì)象
查看全部 -
覆蓋只是在虛函數(shù)列表中將函數(shù)指針替換掉。 如果通過(guò)類(lèi)去訪(fǎng)問(wèn),還是可以訪(fǎng)問(wèn)的。
覆蓋僅指父類(lèi)中有virtual修飾的函數(shù)且子類(lèi)中剛好有同名函數(shù),則發(fā)生覆蓋,
使用父類(lèi)指針指向子類(lèi)對(duì)象時(shí),指向的是繼承的成員函數(shù),而子類(lèi)對(duì)象特有的部分,父類(lèi)對(duì)象無(wú)法實(shí)現(xiàn)訪(fǎng)問(wèn)。
查看全部 -
父類(lèi)有虛析構(gòu)函數(shù),子類(lèi)會(huì)繼承虛析構(gòu)函數(shù)
有虛析構(gòu)函數(shù)的class創(chuàng)建的對(duì)象里有虛函數(shù)指針,占4個(gè)內(nèi)存單元,虛函數(shù)指針指向虛函數(shù)表,虛函數(shù)指針的值是虛函數(shù)表的地址。
查看全部 -
虛析構(gòu)函數(shù)是為了避免使用父類(lèi)指針釋放子類(lèi)對(duì)象時(shí)造成內(nèi)存泄露
查看全部 -
virtrual 不能修飾:
1普通函數(shù)
2靜態(tài)函數(shù)static
3內(nèi)聯(lián)函數(shù)inline
4構(gòu)造函數(shù)
查看全部
舉報(bào)