




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、第第6 6章章 多態(tài)性和虛函數(shù)多態(tài)性和虛函數(shù) l多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計的重要特征之一。多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計的重要特征之一。l多態(tài)性是指多態(tài)性是指發(fā)出同樣的消息被不同類型的對象發(fā)出同樣的消息被不同類型的對象接收時導(dǎo)致完全不同的行為接收時導(dǎo)致完全不同的行為。l消息消息主要指主要指對類的成員函數(shù)的調(diào)用對類的成員函數(shù)的調(diào)用。l多態(tài)的實現(xiàn):多態(tài)的實現(xiàn): 函數(shù)重載函數(shù)重載 運算符重載運算符重載 虛函數(shù)動態(tài):運行時的多態(tài)虛函數(shù)動態(tài):運行時的多態(tài)靜態(tài):編譯時的多態(tài)靜態(tài):編譯時的多態(tài)4/20/20222不同人對不同人對play()請求的響應(yīng)請求的響應(yīng)聯(lián)編(聯(lián)編(binding):是指計算機(jī)程序自身彼此關(guān)聯(lián)
2、的過程是指計算機(jī)程序自身彼此關(guān)聯(lián)的過程聯(lián)編工作在編譯連接階段完成的情況稱為:聯(lián)編工作在編譯連接階段完成的情況稱為:靜態(tài)聯(lián)編靜態(tài)聯(lián)編聯(lián)編在程序運行階段完成的情況稱為:聯(lián)編在程序運行階段完成的情況稱為:動態(tài)聯(lián)編動態(tài)聯(lián)編。第第6 6章章 多態(tài)性和虛函數(shù)多態(tài)性和虛函數(shù) 6.1 6.1 運算符重載運算符重載6.2 6.2 虛函數(shù)虛函數(shù)6.3 6.3 純虛函數(shù)和抽象類純虛函數(shù)和抽象類6.4 6.4 虛析構(gòu)函數(shù)虛析構(gòu)函數(shù)習(xí)題習(xí)題6.1 6.1 運算符重載運算符重載1.運算符重載的實質(zhì)運算符重載的實質(zhì)l運算符重載是對運算符重載是對已有已有的運算符賦予多重含義的運算符賦予多重含義l必要性必要性 C+中預(yù)定義的運
3、算符其運算對象只能是基中預(yù)定義的運算符其運算對象只能是基本數(shù)據(jù)類型,而不適用于用戶自定義類型本數(shù)據(jù)類型,而不適用于用戶自定義類型(如類)(如類)l實現(xiàn)機(jī)制實現(xiàn)機(jī)制 將指定的運算表達(dá)式轉(zhuǎn)化為將指定的運算表達(dá)式轉(zhuǎn)化為對運算符函數(shù)的對運算符函數(shù)的調(diào)用調(diào)用,運算對象運算對象轉(zhuǎn)化為運算符函數(shù)的轉(zhuǎn)化為運算符函數(shù)的實參實參。 編譯系統(tǒng)對重載運算符的選擇,遵循函數(shù)重編譯系統(tǒng)對重載運算符的選擇,遵循函數(shù)重載的選擇原則。載的選擇原則。不能重載的運算符不能重載的運算符是:是:(1) (1) 成員訪問運算符成員訪問運算符. .(2) (2) 作用域運算符作用域運算符(3) (3) 條件運算符條件運算符?:?:(4)
4、(4) 成員指針運算符成員指針運算符* *(5) (5) 編譯預(yù)處理命令的開始符號編譯預(yù)處理命令的開始符號# #l只能重載只能重載C+語言中已有的運算符,不可臆造語言中已有的運算符,不可臆造新的。新的。l不改變原運算符的優(yōu)先級和結(jié)合性。不改變原運算符的優(yōu)先級和結(jié)合性。l不能改變操作數(shù)個數(shù)。不能改變操作數(shù)個數(shù)。l經(jīng)重載的運算符,其操作數(shù)中至少應(yīng)該有一個經(jīng)重載的運算符,其操作數(shù)中至少應(yīng)該有一個是自定義類型。是自定義類型。l重載為類成員函數(shù)。重載為類成員函數(shù)。l重載為友元函數(shù)。重載為友元函數(shù)。可以參考以下的經(jīng)驗:可以參考以下的經(jīng)驗: (1)(1)只能使用只能使用成員函數(shù)成員函數(shù)重載的運算符有:重載的
5、運算符有:= =、()()、-、newnew、deletedelete。 (2)(2)單目運算符最好重載為單目運算符最好重載為成員函數(shù)成員函數(shù)。 (3)(3) 對于復(fù)合的賦值運算符如對于復(fù)合的賦值運算符如+=+=、-=-=、* *= =、/=/=、&=&=、!=!=、=、%=%=、=、=建議重載為建議重載為成員函數(shù)成員函數(shù)。 (4)(4) 對于其它運算符,建議重載為對于其它運算符,建議重載為友元函數(shù)友元函數(shù)。 除了除了賦值運算符賦值運算符外,其它運算符函數(shù)都可以由外,其它運算符函數(shù)都可以由派生類派生類繼承繼承,并且派生類還可有選擇地重載自己所需要的運算,并且派生類還可有選擇地重
6、載自己所需要的運算符(包括基類重載的運算符)。符(包括基類重載的運算符)。 運算符重載的實質(zhì)就是函數(shù)重載。運算符重載的實質(zhì)就是函數(shù)重載。 type operator ( type operator (參數(shù)表參數(shù)表) )若運算符是一元的,則參數(shù)表為空,此時當(dāng)前對象作為此運若運算符是一元的,則參數(shù)表為空,此時當(dāng)前對象作為此運算符的單操作數(shù);若運算符是二元的,則參數(shù)表中有一個操作算符的單操作數(shù);若運算符是二元的,則參數(shù)表中有一個操作數(shù),此時當(dāng)前對象作為此運算符的左操作數(shù),參數(shù)表中的操作數(shù),此時當(dāng)前對象作為此運算符的左操作數(shù),參數(shù)表中的操作數(shù)作為此運算符的右操作數(shù),依此類推。數(shù)作為此運算符的右操作數(shù),
7、依此類推。 運算符函數(shù)的定義方式同一般成員函數(shù),對類成員的訪問與運算符函數(shù)的定義方式同一般成員函數(shù),對類成員的訪問與一般成員函數(shù)相同,定義如下:一般成員函數(shù)相同,定義如下:type type 類名類名:operator operator (參數(shù)表)參數(shù)表) / / 運算符處理程序代碼運算符處理程序代碼 重載運算符的使用方法同原運算符一樣,只是它的操作數(shù)一重載運算符的使用方法同原運算符一樣,只是它的操作數(shù)一定要是定義它的特定類的對象。定要是定義它的特定類的對象。l聲明形式聲明形式函數(shù)類型函數(shù)類型 operator 運算符(形參)運算符(形參) .l重載為類成員函數(shù)時重載為類成員函數(shù)時 參數(shù)個數(shù)參
8、數(shù)個數(shù)=原操作數(shù)個數(shù)原操作數(shù)個數(shù)-1 (后置(后置+、-除外)除外)l重載為友元函數(shù)時重載為友元函數(shù)時 參數(shù)個數(shù)參數(shù)個數(shù)=原操作數(shù)個數(shù)原操作數(shù)個數(shù),且至,且至少應(yīng)該有一個自定義類型的形參。少應(yīng)該有一個自定義類型的形參。例題例題【例【例6.16.1】用成員函數(shù)重載運算符一用成員函數(shù)重載運算符一 【例【例6.26.2】用成員函數(shù)重載運算符二用成員函數(shù)重載運算符二 l雙目運算符雙目運算符 B 如果要重載如果要重載 B 為類成員函數(shù),使之能夠?qū)崿F(xiàn)表為類成員函數(shù),使之能夠?qū)崿F(xiàn)表達(dá)式達(dá)式 oprd1 B oprd2,其中,其中 oprd1 為為A 類對象,類對象,則則 B 應(yīng)被重載為應(yīng)被重載為 A 類的成
9、員函數(shù),形參類型類的成員函數(shù),形參類型應(yīng)該是應(yīng)該是 oprd2 所屬的類型。所屬的類型。 經(jīng)重載后,表達(dá)式經(jīng)重載后,表達(dá)式 oprd1 B oprd2 相當(dāng)于相當(dāng)于 oprd1.operator B(oprd2)l前置單目運算符前置單目運算符 U 如果要重載如果要重載 U 為類成員函數(shù),使之能夠?qū)崿F(xiàn)為類成員函數(shù),使之能夠?qū)崿F(xiàn)表達(dá)式表達(dá)式 U oprd,其中,其中 oprd 為為A類對象,則類對象,則 U 應(yīng)被重載為應(yīng)被重載為 A 類的成員函數(shù),無形參。類的成員函數(shù),無形參。 經(jīng)重載后,經(jīng)重載后,表達(dá)式表達(dá)式 U oprd 相當(dāng)于相當(dāng)于 oprd.operator U( )l后置單目運算符后置單
10、目運算符 +和和- 如果要重載如果要重載 +或或-為類成員函數(shù),使之能夠為類成員函數(shù),使之能夠?qū)崿F(xiàn)表達(dá)式實現(xiàn)表達(dá)式 oprd+ 或或 oprd- ,其中,其中 oprd 為為A類對象,則類對象,則 +或或- 應(yīng)被重載為應(yīng)被重載為 A 類的類的成員函數(shù),且具有一個成員函數(shù),且具有一個 int 類型類型形參形參。 經(jīng)重載后,表達(dá)式經(jīng)重載后,表達(dá)式 oprd+ 相當(dāng)于相當(dāng)于 oprd.operator +(0)補充:補充:l運算符前置運算符前置+和后置和后置+重載為時鐘類的成員函數(shù)。重載為時鐘類的成員函數(shù)。l前置單目運算符,重載函數(shù)沒有形參,對于后置單目前置單目運算符,重載函數(shù)沒有形參,對于后置單目
11、運算符,重載函數(shù)需要有一個整型形參。運算符,重載函數(shù)需要有一個整型形參。l操作數(shù)是時鐘類的對象。操作數(shù)是時鐘類的對象。l實現(xiàn)時間增加實現(xiàn)時間增加1秒鐘。秒鐘。#includeclass Clock /時鐘類聲明時鐘類聲明public:/外部接口外部接口Clock(int NewH=0, int NewM=0, int NewS=0);void ShowTime( );void operator +( ); /前置單目運算符重載前置單目運算符重載void operator +(int); /后置單目運算符重載后置單目運算符重載private:/私有數(shù)據(jù)成員私有數(shù)據(jù)成員int Hour, Minu
12、te, Second;void Clock:operator +( )/前置單目運算符重載函數(shù)前置單目運算符重載函數(shù)Second+;if(Second=60) Second=Second-60;Minute+;if(Minute=60) Minute=Minute-60;Hour+;Hour=Hour%24;cout=60) Second=Second-60;Minute+;if(Minute=60) Minute=Minute-60;Hour+;Hour=Hour%24;coutClock+: ;/其它成員函數(shù)的實現(xiàn)略其它成員函數(shù)的實現(xiàn)略void main( )Clock myClock(2
13、3,59,59);coutFirst time output:;myClock.ShowTime( );myClock+;myClock.ShowTime( );+myClock;myClock.ShowTime( );程序運行結(jié)果為:程序運行結(jié)果為:First time output:23:59:59Clock+: 0:0:0+Clock: 0:0:16.1.3 6.1.3 用友元函數(shù)重載運算符用友元函數(shù)重載運算符friend type operator (friend type operator (參數(shù)表參數(shù)表););注意友元函數(shù)不屬于任何類,它沒有注意友元函數(shù)不屬于任何類,它沒有this
14、this指針指針,這與成員,這與成員函數(shù)完全不同。若運算符是一元的,則參數(shù)表中有一個操作數(shù);函數(shù)完全不同。若運算符是一元的,則參數(shù)表中有一個操作數(shù);若運算符是二元的,則參數(shù)表中有兩個操作數(shù)。也就是說在用若運算符是二元的,則參數(shù)表中有兩個操作數(shù)。也就是說在用友元定義重載運算符時,所有的操作數(shù)均需要用參數(shù)來傳遞。友元定義重載運算符時,所有的操作數(shù)均需要用參數(shù)來傳遞。友元運算符函數(shù)與成員運算符函數(shù)的主要區(qū)別在其參數(shù)個數(shù)不友元運算符函數(shù)與成員運算符函數(shù)的主要區(qū)別在其參數(shù)個數(shù)不同同。當(dāng)運算符的左操作數(shù)是一個常數(shù)時,就不能利用。當(dāng)運算符的左操作數(shù)是一個常數(shù)時,就不能利用thisthis指針,指針,應(yīng)當(dāng)用友
15、元函數(shù)重載。應(yīng)當(dāng)用友元函數(shù)重載。友元運算符函數(shù)的定義如下:友元運算符函數(shù)的定義如下:type type operator (operator (參數(shù)表參數(shù)表) ) / / 運算符處理程序代碼運算符處理程序代碼 例題例題【例【例6.36.3】用友元函數(shù)重載運算符一用友元函數(shù)重載運算符一 【例【例6.46.4】用友元函數(shù)重載運算符實現(xiàn)兩字符串加法用友元函數(shù)重載運算符實現(xiàn)兩字符串加法 參看教材的說明參看教材的說明【例【例6.56.5】用重載運算符的方法進(jìn)行復(fù)數(shù)運算用重載運算符的方法進(jìn)行復(fù)數(shù)運算 1運算符!和運算符!和的重載的重載【例【例6.66.6】運算符!和】運算符!和的重載的重載2前自增和后自增
16、運算符前自增和后自增運算符+的重載的重載前自增運算符前自增運算符+和后自增運算符和后自增運算符+重載的語法重載的語法 operator+(); /operator+(); /前前 operator+(operator+(intint); /); /后后【例【例6.76.7】用成員函數(shù)重載前自增和后自增運算符?!坑贸蓡T函數(shù)重載前自增和后自增運算符?!纠纠?.86.8】用友元重載前自增和后自增用友元重載前自增和后自增 3運算符運算符-的重載的重載-運算符是成員訪問運算符,這種一元的運算符只能被重載為運算符是成員訪問運算符,這種一元的運算符只能被重載為成員函數(shù),成員訪問運算符成員函數(shù),成員訪問運算
17、符-函數(shù)重載的一般形式為:函數(shù)重載的一般形式為:【例例6.96.9】重載】重載-運算符。運算符。在正常的情況下,系統(tǒng)會為每一個類自動生成一在正常的情況下,系統(tǒng)會為每一個類自動生成一個默認(rèn)的完成上述功能的賦值運算符,當(dāng)然,這種個默認(rèn)的完成上述功能的賦值運算符,當(dāng)然,這種賦值只限于同一個類類型說明的對象之間賦值,相賦值只限于同一個類類型說明的對象之間賦值,相當(dāng)于淺拷貝構(gòu)造函數(shù)。當(dāng)于淺拷貝構(gòu)造函數(shù)。【例例6.106.10】賦值運算符的重載一?!抠x值運算符的重載一。【例例6.116.11】賦值運算符的重載二。】賦值運算符的重載二。【例例6.126.12】賦值運算符的重載三?!抠x值運算符的重載三。 6.
18、2 6.2 虛函數(shù)虛函數(shù) 指向基類對象的指針都可以指向它的公有派生類對象,若指向基類對象的指針都可以指向它的公有派生類對象,若試圖指向它的私有派生類對象是被禁止的。試圖指向它的私有派生類對象是被禁止的。不能將一個聲明為不能將一個聲明為指向派生類對象的指針指向其基類的一個對象。指向派生類對象的指針指向其基類的一個對象。 聲明為指向基類對象的指針,當(dāng)它指向公有派生類對象時,聲明為指向基類對象的指針,當(dāng)它指向公有派生類對象時,只能利用它來直接訪問派生類中從基類繼承來的成員,不能直只能利用它來直接訪問派生類中從基類繼承來的成員,不能直接訪問公有派生類中特定的成員。接訪問公有派生類中特定的成員。若想訪問
19、其公有派生類的特若想訪問其公有派生類的特定成員,可以將基類指針顯式類型轉(zhuǎn)換為派生類指針來實現(xiàn)。定成員,可以將基類指針顯式類型轉(zhuǎn)換為派生類指針來實現(xiàn)。 【例【例6.146.14】為什么要引入虛函數(shù)為什么要引入虛函數(shù)6.2.2 6.2.2 虛函數(shù)的定義與使用虛函數(shù)的定義與使用 1 1虛函數(shù)的定義虛函數(shù)的定義 虛函數(shù)是引入了派生概念后,用來表現(xiàn)基類和派虛函數(shù)是引入了派生概念后,用來表現(xiàn)基類和派生類的成員函數(shù)之間的一種關(guān)系的。生類的成員函數(shù)之間的一種關(guān)系的。虛函數(shù)定義是在虛函數(shù)定義是在基類中進(jìn)行的(基類中進(jìn)行的(virtualvirtual), ,虛函數(shù)提供了一種接口界虛函數(shù)提供了一種接口界面。在基類
20、中的某個成員函數(shù)被聲明為虛函數(shù)后,此面。在基類中的某個成員函數(shù)被聲明為虛函數(shù)后,此虛函數(shù)就可以在一個或多個派生類中被重新定義。虛函數(shù)就可以在一個或多個派生類中被重新定義。在在派生類中重新定義虛函數(shù)時,都必須與基類中的派生類中重新定義虛函數(shù)時,都必須與基類中的原型原型完全相同完全相同。 虛函數(shù)是一種虛函數(shù)是一種非靜態(tài)非靜態(tài)的成員函數(shù),說明虛函數(shù)的的成員函數(shù),說明虛函數(shù)的方法如下:方法如下: virtual virtual 類型函數(shù)名(參數(shù)表)類型函數(shù)名(參數(shù)表)使用虛函數(shù)時應(yīng)注意以下幾點使用虛函數(shù)時應(yīng)注意以下幾點(1):(1): (1) (1) 虛函數(shù)是在基類和派生類中說明相同而實現(xiàn)不同的成員函
21、數(shù),在虛函數(shù)是在基類和派生類中說明相同而實現(xiàn)不同的成員函數(shù),在派生類中重新定義基類中的虛函數(shù)時,可以不加派生類中重新定義基類中的虛函數(shù)時,可以不加virtualvirtual,因為因為虛特虛特性可以傳遞性可以傳遞,但,但函數(shù)原型必須與基類中的完全相同,否則會丟失虛特函數(shù)原型必須與基類中的完全相同,否則會丟失虛特性。性。(2) (2) 基類中說明的虛函數(shù)具有下傳給派生類的性質(zhì)?;愔姓f明的虛函數(shù)具有下傳給派生類的性質(zhì)。(3) (3) 析構(gòu)函數(shù)可以是的虛函數(shù),但構(gòu)造函數(shù)則不能是虛函數(shù)。析構(gòu)函數(shù)可以是的虛函數(shù),但構(gòu)造函數(shù)則不能是虛函數(shù)。一般地一般地講,若某類中定義有虛函數(shù),則其析構(gòu)函數(shù)也應(yīng)當(dāng)說明為虛
22、函數(shù)。特講,若某類中定義有虛函數(shù),則其析構(gòu)函數(shù)也應(yīng)當(dāng)說明為虛函數(shù)。特別是在析構(gòu)函數(shù)需要完成一些有意義的操作別是在析構(gòu)函數(shù)需要完成一些有意義的操作比如釋放內(nèi)存時,尤比如釋放內(nèi)存時,尤其應(yīng)當(dāng)如此。其應(yīng)當(dāng)如此。(4) (4) 在類體系中訪問一個虛函數(shù)時,應(yīng)使用指向基類的指針或?qū)愒陬愺w系中訪問一個虛函數(shù)時,應(yīng)使用指向基類的指針或?qū)惖囊?,以滿足運行時多態(tài)性的要求的引用,以滿足運行時多態(tài)性的要求。當(dāng)然也可以像調(diào)用普通成員函。當(dāng)然也可以像調(diào)用普通成員函數(shù)那樣利用對象名來調(diào)用一個虛函數(shù)這時會丟失虛特性。數(shù)那樣利用對象名來調(diào)用一個虛函數(shù)這時會丟失虛特性。(5) (5) 在派生類中重新定義虛函數(shù)時,在派
23、生類中重新定義虛函數(shù)時,必須保證派生類中該函數(shù)的返必須保證派生類中該函數(shù)的返回值和參數(shù)與基類中的說明完全一致,回值和參數(shù)與基類中的說明完全一致,否則就屬于重載(如果參數(shù)否則就屬于重載(如果參數(shù)不同)或是一個錯誤(參數(shù)相同,僅返回值不同)。不同)或是一個錯誤(參數(shù)相同,僅返回值不同)。(6) (6) 若在派生類中沒有重新定義虛函數(shù),則派生類的對象將使用其若在派生類中沒有重新定義虛函數(shù),則派生類的對象將使用其基類中的虛函數(shù)代碼?;愔械奶摵瘮?shù)代碼。(7) (7) 虛函數(shù)必須是類的一個成員函數(shù),不能是友元,但它可以是另虛函數(shù)必須是類的一個成員函數(shù),不能是友元,但它可以是另一個類的友元。另外,一個類的
24、友元。另外,虛函數(shù)不能是一個靜態(tài)成員函數(shù)。虛函數(shù)不能是一個靜態(tài)成員函數(shù)。(8)(8)構(gòu)造函數(shù)只能用構(gòu)造函數(shù)只能用inlineinline進(jìn)行修飾,不能是虛函數(shù)進(jìn)行修飾,不能是虛函數(shù)。 (9) (9) 一個類的虛函數(shù)僅對派生類中重定義的函數(shù)起作用,對其它函一個類的虛函數(shù)僅對派生類中重定義的函數(shù)起作用,對其它函數(shù)沒有影響。在基類中使用虛函數(shù)保證了通過指向基類對象的指針數(shù)沒有影響。在基類中使用虛函數(shù)保證了通過指向基類對象的指針調(diào)用基類的一個虛函數(shù)時,調(diào)用基類的一個虛函數(shù)時,C+C+系統(tǒng)對該調(diào)用進(jìn)行系統(tǒng)對該調(diào)用進(jìn)行動態(tài)綁定動態(tài)綁定,而使用,而使用普通函數(shù)則是靜態(tài)綁定。普通函數(shù)則是靜態(tài)綁定。使用虛函數(shù)時
25、應(yīng)注意以下幾點使用虛函數(shù)時應(yīng)注意以下幾點(2):(2): (10)(10) 使用虛函數(shù)方法后,不得再使用類作用域區(qū)分使用虛函數(shù)方法后,不得再使用類作用域區(qū)分符強(qiáng)制指明要引用的虛函數(shù)。因為此法將破壞多態(tài)性符強(qiáng)制指明要引用的虛函數(shù)。因為此法將破壞多態(tài)性而使編譯器無所適從。而使編譯器無所適從。(11)(11) 若派生類中沒有再定義基類中已有的虛函數(shù),若派生類中沒有再定義基類中已有的虛函數(shù),則指向該類對象的指針或引用名引用虛函數(shù)時總是引則指向該類對象的指針或引用名引用虛函數(shù)時總是引用距離其最近的一個基類中的虛函數(shù)。用距離其最近的一個基類中的虛函數(shù)。(12)(12) 若在基類的構(gòu)造(析構(gòu))函數(shù)中也引用虛
26、函數(shù),若在基類的構(gòu)造(析構(gòu))函數(shù)中也引用虛函數(shù),則所引用的只能是本類的虛函數(shù),因為此時派生類中則所引用的只能是本類的虛函數(shù),因為此時派生類中的構(gòu)造(析構(gòu))函數(shù)的執(zhí)行尚未完成。的構(gòu)造(析構(gòu))函數(shù)的執(zhí)行尚未完成。使用虛函數(shù)時應(yīng)注意以下幾點使用虛函數(shù)時應(yīng)注意以下幾點(3):(3): 2. 2. 虛函數(shù)與重載函數(shù)的關(guān)系虛函數(shù)與重載函數(shù)的關(guān)系(1) (1) 重載函數(shù)要求函數(shù)有相同的返回值類型和函數(shù)名重載函數(shù)要求函數(shù)有相同的返回值類型和函數(shù)名稱,并有不同的參數(shù)序列;而虛函數(shù)則要求這三項稱,并有不同的參數(shù)序列;而虛函數(shù)則要求這三項(函數(shù)名、返回值類型和參數(shù)序列)完全相同;(函數(shù)名、返回值類型和參數(shù)序列)完全
27、相同;(2) (2) 重載函數(shù)可以是成員函數(shù)或友員函數(shù),而虛函數(shù)重載函數(shù)可以是成員函數(shù)或友員函數(shù),而虛函數(shù)只能是成員函數(shù);只能是成員函數(shù);(3) (3) 重載函數(shù)的調(diào)用是以所傳遞參數(shù)序列的差別作為重載函數(shù)的調(diào)用是以所傳遞參數(shù)序列的差別作為調(diào)用不同函數(shù)的依據(jù);虛函數(shù)是根據(jù)對象的不同去調(diào)調(diào)用不同函數(shù)的依據(jù);虛函數(shù)是根據(jù)對象的不同去調(diào)用不同類的虛函數(shù);用不同類的虛函數(shù);(4) (4) 虛函數(shù)在運行時表現(xiàn)出多態(tài)功能,這是虛函數(shù)在運行時表現(xiàn)出多態(tài)功能,這是C+C+的精的精髓;而重載函數(shù)則在編譯時表現(xiàn)出多態(tài)性。髓;而重載函數(shù)則在編譯時表現(xiàn)出多態(tài)性。 3 3虛函數(shù)的使用虛函數(shù)的使用 定義一個基類類型的對象指
28、針或引用便可使其在需要定義一個基類類型的對象指針或引用便可使其在需要時指向相應(yīng)的類對象,并用此指針或引用去引用該對象時指向相應(yīng)的類對象,并用此指針或引用去引用該對象所對應(yīng)的類中已被所對應(yīng)的類中已被“虛擬化虛擬化”的函數(shù),從而可以實現(xiàn)真的函數(shù),從而可以實現(xiàn)真正的運行時的多態(tài)性。正的運行時的多態(tài)性。【例【例6.166.16】虛函數(shù)的使用舉例。虛函數(shù)的使用舉例?!纠纠?.176.17】異質(zhì)鏈表的實現(xiàn)】異質(zhì)鏈表的實現(xiàn):有三個類:有三個類studentstudent、teacherteacher、staffstaff,再定義一個鏈表類,此類用來存放這再定義一個鏈表類,此類用來存放這幾個不同類的對象;并
29、將鏈表幾個不同類的對象;并將鏈表listlist聲明為所有這些類的聲明為所有這些類的友元,使它可以訪問它們的私有成員。友元,使它可以訪問它們的私有成員。 4 4在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù)在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù)在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù)時,在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù)時,采用靜態(tài)聯(lián)編,即它們所調(diào)用的虛函數(shù)是自己采用靜態(tài)聯(lián)編,即它們所調(diào)用的虛函數(shù)是自己的類或基類中定義的函數(shù)而不是在任何派生類的類或基類中定義的函數(shù)而不是在任何派生類中重定義的函數(shù)。同樣,使用對象調(diào)用虛函數(shù)中重定義的函數(shù)。同樣,使用對象調(diào)用虛函數(shù)也采用靜態(tài)聯(lián)編。也采用靜態(tài)聯(lián)編?!纠纠?.186.18】在構(gòu)造
30、函數(shù)中調(diào)用虛函數(shù)在構(gòu)造函數(shù)中調(diào)用虛函數(shù)5 5空的虛函數(shù)空的虛函數(shù) 派生類并不一定必須實現(xiàn)基類中的虛派生類并不一定必須實現(xiàn)基類中的虛函數(shù),如果派生類想通過虛函數(shù)機(jī)制存取虛函函數(shù),如果派生類想通過虛函數(shù)機(jī)制存取虛函數(shù),則必須建立一條從基類到派生類的虛函數(shù)數(shù),則必須建立一條從基類到派生類的虛函數(shù)路徑。許多沒有使用虛函數(shù)的中間類也必須聲路徑。許多沒有使用虛函數(shù)的中間類也必須聲明該函數(shù),以保證其后的派生類能使用該虛函明該函數(shù),以保證其后的派生類能使用該虛函數(shù)??梢酝ㄟ^聲明空函數(shù)來達(dá)到此目的。數(shù)??梢酝ㄟ^聲明空函數(shù)來達(dá)到此目的。 【例【例6.196.19】空虛函數(shù)空虛函數(shù) 6.3 6.3 純虛函數(shù)和抽象類
31、純虛函數(shù)和抽象類6.3.1 6.3.1 純虛函數(shù)的概念純虛函數(shù)的概念 如果基類只表達(dá)一些抽象的概念,而并不與具體的對如果基類只表達(dá)一些抽象的概念,而并不與具體的對象相聯(lián)系,但它又必須為它的派生類提供一個公共的界面,象相聯(lián)系,但它又必須為它的派生類提供一個公共的界面,在這種情況下,可以將基類中的虛函數(shù)定義成純虛函數(shù)。在這種情況下,可以將基類中的虛函數(shù)定義成純虛函數(shù)。純虛函數(shù)是一種沒有具體實現(xiàn)的特殊的虛函數(shù)。純虛函數(shù)是一種沒有具體實現(xiàn)的特殊的虛函數(shù)。一個基類一個基類中有一個純虛函數(shù)時,則在它的派生類中至少有一個虛函中有一個純虛函數(shù)時,則在它的派生類中至少有一個虛函數(shù),否則純虛函數(shù)是無意義的。數(shù),否
32、則純虛函數(shù)是無意義的。純虛函數(shù)的定義格式如下:純虛函數(shù)的定義格式如下: virtual virtual 類型類型( (函數(shù)名函數(shù)名)()(參數(shù)表參數(shù)表)=0)=0; 由于純虛函數(shù)所在的類中沒有它的定義,在該類的構(gòu)由于純虛函數(shù)所在的類中沒有它的定義,在該類的構(gòu)造函數(shù)和析構(gòu)函數(shù)中不允許調(diào)用純虛函數(shù),否則會導(dǎo)致程造函數(shù)和析構(gòu)函數(shù)中不允許調(diào)用純虛函數(shù),否則會導(dǎo)致程序運行錯誤。但其它成員函數(shù)可以調(diào)用純虛函數(shù)。序運行錯誤。但其它成員函數(shù)可以調(diào)用純虛函數(shù)。6.3.2 6.3.2 抽象類的概念抽象類的概念 1 1抽象類和具體類的概念抽象類和具體類的概念 如果一個類至少有一個純虛函數(shù),那么就稱該類為如果一個類至
33、少有一個純虛函數(shù),那么就稱該類為抽象類抽象類。能夠建立實例化對象的類稱為具體類,也就。能夠建立實例化對象的類稱為具體類,也就是不含純虛函數(shù)的類為具體類。是不含純虛函數(shù)的類為具體類。 抽象類的主要作用是為其所組織的繼承層次結(jié)構(gòu)抽象類的主要作用是為其所組織的繼承層次結(jié)構(gòu)提供一個公共的基類,它刻劃了公有行為的特征,其提供一個公共的基類,它刻劃了公有行為的特征,其它類可以從它這里繼承和實現(xiàn)接口,純虛函數(shù)的實現(xiàn)它類可以從它這里繼承和實現(xiàn)接口,純虛函數(shù)的實現(xiàn)由其具體的派生類來提供。由其具體的派生類來提供。2 2對抽象類的幾點規(guī)定對抽象類的幾點規(guī)定(1) (1) 抽象類只能作為基類來派生新類,抽象類只能作為
34、基類來派生新類,不能建立不能建立抽象類的對象。抽象類的對象。(2) (2) 抽象類抽象類不能不能用作參數(shù)類型、函數(shù)返回值類型、用作參數(shù)類型、函數(shù)返回值類型、或顯式轉(zhuǎn)換的類型?;蝻@式轉(zhuǎn)換的類型。(3) (3) 可以聲明指向抽象類的指針和引用,此指針可以聲明指向抽象類的指針和引用,此指針可以指向它的公有派生類,進(jìn)而實現(xiàn)多態(tài)性??梢灾赶蛩墓信缮?,進(jìn)而實現(xiàn)多態(tài)性。(4) (4) 從一個抽象類派生的從一個抽象類派生的具體類具體類必須提供純虛函必須提供純虛函數(shù)的實現(xiàn)代碼。數(shù)的實現(xiàn)代碼。(5) (5) 如果基類中含有純虛函數(shù),而其派生類卻并如果基類中含有純虛函數(shù),而其派生類卻并沒有重新定義這些純虛函數(shù)
35、的覆蓋成員函數(shù),那么這沒有重新定義這些純虛函數(shù)的覆蓋成員函數(shù),那么這個派生類也是抽象類,因此也不能用來定義對象。但個派生類也是抽象類,因此也不能用來定義對象。但此情況不會影響以后的派生類。此情況不會影響以后的派生類。(6) (6) 含有純虛函數(shù)的類中可以包含非純虛函數(shù),但這含有純虛函數(shù)的類中可以包含非純虛函數(shù),但這些虛函數(shù)只能通過其派生類的對象才能被引用。些虛函數(shù)只能通過其派生類的對象才能被引用。(7) (7) 如果派生類中給出了基類所有純虛函數(shù)的實現(xiàn),如果派生類中給出了基類所有純虛函數(shù)的實現(xiàn),則該派生類不再是抽象類。則該派生類不再是抽象類。(8)(8)在成員函數(shù)內(nèi)可以調(diào)用純虛函數(shù)(程序員很少
36、這樣在成員函數(shù)內(nèi)可以調(diào)用純虛函數(shù)(程序員很少這樣做),但在構(gòu)造函數(shù)或析構(gòu)函數(shù)內(nèi)調(diào)用純虛函數(shù)將導(dǎo)做),但在構(gòu)造函數(shù)或析構(gòu)函數(shù)內(nèi)調(diào)用純虛函數(shù)將導(dǎo)致程序連接有錯誤,因為沒有為純虛函數(shù)定義代碼。致程序連接有錯誤,因為沒有為純虛函數(shù)定義代碼。3 3抽象類舉例抽象類舉例【例【例6.206.20】計算各類形狀的總面積。計算各類形狀的總面積。6.4 6.4 虛析構(gòu)函數(shù)虛析構(gòu)函數(shù)(1)(1)6.4 6.4 虛析構(gòu)函數(shù)虛析構(gòu)函數(shù)(2)(2)【例【例6.21】虛析構(gòu)函數(shù)的使用虛析構(gòu)函數(shù)的使用。 習(xí)習(xí) 題題 (1) (1)1. 1. 虛函數(shù)和重載設(shè)計方法上有何相同和不同之處?虛函數(shù)和重載設(shè)計方法上有何相同和不同之處?2. 2. 什么是純虛函數(shù)?什么是抽象類?什么是純虛函數(shù)?什么是抽象類?抽象類的特性抽象類的特性是什么?是什么?3. 3. 給字符串類定義下列重載運算符函數(shù):給字符串類定義下列重載運算符函數(shù):(1) (1) 賦值運算符賦值運算符= =(2) (
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 跨領(lǐng)域合作下的設(shè)計軟件發(fā)展趨勢分析
- 超市火源管理與防火監(jiān)督的實踐探索
- 內(nèi)蒙古2025年01月內(nèi)蒙古東烏珠穆沁旗事業(yè)單位引進(jìn)9名急需緊缺人才筆試歷年典型考題(歷年真題考點)解題思路附帶答案詳解
- 跨學(xué)科合作在提高血液透析安全管理中的應(yīng)用
- 小學(xué)英語課堂游戲單詞字母句子類游戲陷阱
- 高中語文情感美文守護(hù)你一輩子
- 初中語文文言文庭中有奇樹原文譯文與詩詞鑒賞
- 非營利組織的財務(wù)管理技巧與實務(wù)
- 學(xué)校畢業(yè)聯(lián)歡會主持人開場白模板(30篇)
- 高效財務(wù)管理軟件應(yīng)用實戰(zhàn)指南
- 網(wǎng)絡(luò)安全風(fēng)險評估報告模板
- 蘋果種植養(yǎng)護(hù)培訓(xùn)課件
- 什么是法律談判課件
- 成考教材-數(shù)學(xué)教程(文史財經(jīng)類)
- 保安服務(wù)管理制度范文
- 汽車行業(yè)維修記錄管理制度
- 老年護(hù)理團(tuán)隊建設(shè)方案
- 《跨學(xué)科實踐活動3 水質(zhì)檢測及自制凈水器》教學(xué)設(shè)計
- 起重吊裝作業(yè)安全培訓(xùn)考核試卷
- 開塞露的使用
- 中建《質(zhì)量標(biāo)準(zhǔn)化管理手冊》水利水電工程
評論
0/150
提交評論