本期是C++基礎(chǔ)語(yǔ)法分享的第七節(jié),今天給大家來(lái)分享一下:
(1)虛析構(gòu)函數(shù);
(2)純虛函數(shù);
(3)虛函數(shù)、純虛函數(shù);
(4)虛函數(shù)指針、虛函數(shù)表;
(5)虛繼承;
(6)虛繼承、虛函數(shù);
(7)模板類(lèi)、成員模板、虛函數(shù);
(8)抽象類(lèi)、接口類(lèi)、聚合類(lèi);
虛析構(gòu)函數(shù)
虛析構(gòu)函數(shù)是為了解決基類(lèi)的指針指向派生類(lèi)對(duì)象,并用基類(lèi)的指針刪除派生類(lèi)對(duì)象。
虛析構(gòu)函數(shù)使用
class Shape{public: Shape(); // 構(gòu)造函數(shù)不能是虛函數(shù) virtual double calcArea(); virtual ~Shape(); // 虛析構(gòu)函數(shù)};class Circle : public Shape // 圓形類(lèi){public: virtual double calcArea(); 。。。};int main(){ Shape * shape1 = new Circle(4.0); shape1-》calcArea(); delete shape1; // 因?yàn)镾hape有虛析構(gòu)函數(shù),所以delete釋放內(nèi)存時(shí),先調(diào)用子類(lèi)析構(gòu)函數(shù),再調(diào)用基類(lèi)析構(gòu)函數(shù),防止內(nèi)存泄漏。 shape1 = NULL; return 0;}
純虛函數(shù)
純虛函數(shù)是一種特殊的虛函數(shù),在基類(lèi)中不能對(duì)虛函數(shù)給出有意義的實(shí)現(xiàn),而把它聲明為純虛函數(shù),它的實(shí)現(xiàn)留給該基類(lèi)的派生類(lèi)去做。
virtual int A() = 0;
虛函數(shù)、純虛函數(shù)
類(lèi)里如果聲明了虛函數(shù),這個(gè)函數(shù)是實(shí)現(xiàn)的,哪怕是空實(shí)現(xiàn),它的作用就是為了能讓這個(gè)函數(shù)在它的子類(lèi)里面可以被覆蓋(override),這樣的話,編譯器就可以使用后期綁定來(lái)達(dá)到多態(tài)了。純虛函數(shù)只是一個(gè)接口,是個(gè)函數(shù)的聲明而已,它要留到子類(lèi)里去實(shí)現(xiàn)。
虛函數(shù)在子類(lèi)里面可以不重寫(xiě);但純虛函數(shù)必須在子類(lèi)實(shí)現(xiàn)才可以實(shí)例化子類(lèi)。
虛函數(shù)的類(lèi)用于 “實(shí)作繼承”,繼承接口的同時(shí)也繼承了父類(lèi)的實(shí)現(xiàn)。純虛函數(shù)關(guān)注的是接口的統(tǒng)一性,實(shí)現(xiàn)由子類(lèi)完成。
帶純虛函數(shù)的類(lèi)叫抽象類(lèi),這種類(lèi)不能直接生成對(duì)象,而只有被繼承,并重寫(xiě)其虛函數(shù)后,才能使用。抽象類(lèi)被繼承后,子類(lèi)可以繼續(xù)是抽象類(lèi),也可以是普通類(lèi)。
虛基類(lèi)是虛繼承中的基類(lèi),暫不做詳細(xì)說(shuō)明。
虛函數(shù)指針、虛函數(shù)表
虛函數(shù)指針:在含有虛函數(shù)類(lèi)的對(duì)象中,指向虛函數(shù)表,在運(yùn)行時(shí)確定。
虛函數(shù)表:在程序只讀數(shù)據(jù)段,存放虛函數(shù)指針,如果派生類(lèi)實(shí)現(xiàn)了基類(lèi)的某個(gè)虛函數(shù),則在虛表中覆蓋原本基類(lèi)的那個(gè)虛函數(shù)指針,在編譯時(shí)根據(jù)類(lèi)的聲明創(chuàng)建。
虛繼承
虛繼承用于解決多繼承條件下的菱形繼承問(wèn)題(浪費(fèi)存儲(chǔ)空間、存在二義性)。
底層實(shí)現(xiàn)原理與編譯器相關(guān),一般通過(guò)虛基類(lèi)指針和虛基類(lèi)表實(shí)現(xiàn),每個(gè)虛繼承的子類(lèi)都有一個(gè)虛基類(lèi)指針(占用一個(gè)指針的存儲(chǔ)空間,4字節(jié))和虛基類(lèi)表(不占用類(lèi)對(duì)象的存儲(chǔ)空間)(需要強(qiáng)調(diào)的是,虛基類(lèi)依舊會(huì)在子類(lèi)里面存在拷貝,只是僅僅最多存在一份而已,并不是不在子類(lèi)里面了);當(dāng)虛繼承的子類(lèi)被當(dāng)做父類(lèi)繼承時(shí),虛基類(lèi)指針也會(huì)被繼承。
實(shí)際上,vbptr 指的是虛基類(lèi)表指針(virtual base table pointer),該指針指向了一個(gè)虛基類(lèi)表(virtual table),虛表中記錄了虛基類(lèi)與本類(lèi)的偏移地址;通過(guò)偏移地址,這樣就找到了虛基類(lèi)成員,而虛繼承也不用像普通多繼承那樣維持著公共基類(lèi)(虛基類(lèi))的兩份同樣的拷貝,節(jié)省了存儲(chǔ)空間。
虛繼承、虛函數(shù)
相同之處:都利用了虛指針(均占用類(lèi)的存儲(chǔ)空間)和虛表(均不占用類(lèi)的存儲(chǔ)空間)
不同之處:
虛繼承
(1)虛基類(lèi)依舊存在繼承類(lèi)中,只占用存儲(chǔ)空間
(2)虛基類(lèi)表存儲(chǔ)的是虛基類(lèi)相對(duì)直接繼承類(lèi)的偏移
虛函數(shù)
(1)虛函數(shù)不占用存儲(chǔ)空間
(2)虛函數(shù)表存儲(chǔ)的是虛函數(shù)地址
模板類(lèi)、成員模板、虛函數(shù)
模板類(lèi)中可以使用虛函數(shù)
一個(gè)類(lèi)(無(wú)論是普通類(lèi)還是類(lèi)模板)的成員模板(本身是模板的成員函數(shù))不能是虛函數(shù)
抽象類(lèi)、接口類(lèi)、聚合類(lèi)
抽象類(lèi):含有純虛函數(shù)的類(lèi)
接口類(lèi):僅含有純虛函數(shù)的抽象類(lèi)
聚合類(lèi):用戶可以直接訪問(wèn)其成員,并且具有特殊的初始化語(yǔ)法形式。滿足如下特點(diǎn):
(1)所有成員都是 public
(2)沒(méi)有定義任何構(gòu)造函數(shù)
(3)沒(méi)有類(lèi)內(nèi)初始化
(4)沒(méi)有基類(lèi),也沒(méi)有 virtual 函數(shù)
今天的分享就到這里了,大家要好好學(xué)C++喲~
編輯:jq
-
Virtual
+關(guān)注
關(guān)注
0文章
23瀏覽量
12732 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4421瀏覽量
67815 -
指針
+關(guān)注
關(guān)注
1文章
484瀏覽量
71947
原文標(biāo)題:C++基礎(chǔ)語(yǔ)法梳理:虛函數(shù)及其相關(guān)知識(shí)點(diǎn)
文章出處:【微信號(hào):cyuyanxuexi,微信公眾號(hào):C語(yǔ)言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
示波器小知識(shí)點(diǎn)
【黑金云課堂筆記】第三期知識(shí)點(diǎn)總結(jié)
Linux內(nèi)核伙伴系統(tǒng)內(nèi)存申請(qǐng)函數(shù)詳解:從原理到實(shí)戰(zhàn)
一文帶你徹底搞懂K8s網(wǎng)絡(luò)
跨阻放大器的虛短虛斷如何分析以及電流的流向?
【「Yocto項(xiàng)目實(shí)戰(zhàn)教程:高效定制嵌入式Linux系統(tǒng)」閱讀體驗(yàn)】01初讀體驗(yàn)
激光焊錫中虛焊產(chǎn)生的原因和解決方法
一文詳解開(kāi)關(guān)電源反饋環(huán)路設(shè)計(jì)
【「# 運(yùn)算放大器參數(shù)解析與LTspice應(yīng)用仿真」閱讀體驗(yàn)】+全書(shū)概覽與第一章閱讀分享
什么是運(yùn)放的虛短和虛斷
C51單片機(jī)及C語(yǔ)言知識(shí)點(diǎn)必備秘籍
【必看】開(kāi)關(guān)電源中每一個(gè)元器件的計(jì)算+51頁(yè)圖文詳解
電機(jī)選型計(jì)算公式與知識(shí)點(diǎn)匯總
模擬電路入門(mén)100個(gè)知識(shí)點(diǎn)
詳解錫膏工藝中的虛焊現(xiàn)象
一文詳解虛函數(shù)及其相關(guān)知識(shí)點(diǎn)
評(píng)論