




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第第7章章 多態(tài)性與虛函數(shù)多態(tài)性與虛函數(shù) 多態(tài)性是面向?qū)ο蟪绦蛟O計的重要特征多態(tài)性是面向?qū)ο蟪绦蛟O計的重要特征之一,多態(tài)性機制:之一,多態(tài)性機制:n 增加了面向?qū)ο筌浖到y(tǒng)的靈活性增加了面向?qū)ο筌浖到y(tǒng)的靈活性n 減少了冗余信息減少了冗余信息n 提高了軟件的可重用性和可擴充性提高了軟件的可重用性和可擴充性7.1 多態(tài)性概述多態(tài)性概述 指不同對象收到相同的消息時,產(chǎn)指不同對象收到相同的消息時,產(chǎn)生不同的動作。生不同的動作。 多態(tài)性是指用一個名字定義不同的多態(tài)性是指用一個名字定義不同的函數(shù),這些函數(shù)執(zhí)行不同但又類似的操函數(shù),這些函數(shù)執(zhí)行不同但又類似的操作,從而可以作,從而可以使用相同的調(diào)用方式來調(diào)
2、使用相同的調(diào)用方式來調(diào)用這些具有不同功能的同名函數(shù)。用這些具有不同功能的同名函數(shù)。 C+中的多態(tài)性可以分為四類中的多態(tài)性可以分為四類:n參數(shù)多態(tài):參數(shù)多態(tài):由由類模板類模板實例化各個類都有的具有相同的實例化各個類都有的具有相同的操作,而操作對象的類型卻各不相同操作,而操作對象的類型卻各不相同n包含多態(tài):包含多態(tài):主要通過主要通過虛函數(shù)虛函數(shù)來實現(xiàn)。強調(diào)不同類中的來實現(xiàn)。強調(diào)不同類中的同名成員函數(shù)的多態(tài)行為同名成員函數(shù)的多態(tài)行為n強制多態(tài):強制多態(tài):即,即,將一個變元的類型加以變化將一個變元的類型加以變化,比如加,比如加法運算時候浮點數(shù)與整數(shù)的強制轉(zhuǎn)換(編譯程序通過法運算時候浮點數(shù)與整數(shù)的強制轉(zhuǎn)
3、換(編譯程序通過語義操作,把操作對象的類型強行加以變換,以符合語義操作,把操作對象的類型強行加以變換,以符合函數(shù)或操作符的要求)函數(shù)或操作符的要求)n重載多態(tài):重載多態(tài):普通函數(shù)、類的成員函數(shù)的重載、運算符普通函數(shù)、類的成員函數(shù)的重載、運算符重載重載屬于重載多態(tài)。屬于重載多態(tài)。 前面兩種統(tǒng)稱為通用多態(tài),而后面兩種統(tǒng)稱為專前面兩種統(tǒng)稱為通用多態(tài),而后面兩種統(tǒng)稱為專用多態(tài)。用多態(tài)。 是通過是通過靜態(tài)聯(lián)編靜態(tài)聯(lián)編來實現(xiàn)的。靜態(tài)聯(lián)編就是來實現(xiàn)的。靜態(tài)聯(lián)編就是在編譯階段完成的聯(lián)編。編譯時多態(tài)性主要是在編譯階段完成的聯(lián)編。編譯時多態(tài)性主要是通過通過和運算符重載和運算符重載實現(xiàn)的。實現(xiàn)的。 是用是用動態(tài)聯(lián)編
4、動態(tài)聯(lián)編實現(xiàn)的。動態(tài)聯(lián)編是運行階實現(xiàn)的。動態(tài)聯(lián)編是運行階段完成的聯(lián)編。運行時多態(tài)性主要是通過段完成的聯(lián)編。運行時多態(tài)性主要是通過虛函虛函數(shù)數(shù)來實現(xiàn)的。來實現(xiàn)的。 7.2 運算符重載運算符重載n重載,即重新賦予新的含義。重載,即重新賦予新的含義。n函數(shù)重載就是對一個已有的函數(shù)賦予新函數(shù)重載就是對一個已有的函數(shù)賦予新的含義,使之實現(xiàn)新功能。的含義,使之實現(xiàn)新功能。什么是運算符重載?什么是運算符重載?n運算符也可以重載,對運算符也可以重載,對C+已提供的運已提供的運算符進行重載,賦予它們新的含義,使算符進行重載,賦予它們新的含義,使之一名多用。譬如,用之一名多用。譬如,用“+”號如何進行號如何進行兩
5、個復數(shù)的相加兩個復數(shù)的相加? C+中不能直接用運中不能直接用運算符算符“+”對復數(shù)進行相加運算。對復數(shù)進行相加運算。n可以通過定義一個專門的函數(shù)來實現(xiàn)復數(shù)相加??梢酝ㄟ^定義一個專門的函數(shù)來實現(xiàn)復數(shù)相加。 n例例7.1 通過通過函數(shù)函數(shù)來實現(xiàn)復數(shù)相加。來實現(xiàn)復數(shù)相加。#include using namespace std;class Complex /定義定義Complex類類public:Complex( )real=0;imag=0; /定義構(gòu)造函數(shù)定義構(gòu)造函數(shù)Complex(double r,double i) /構(gòu)造函數(shù)重載構(gòu)造函數(shù)重載real=r; imag=i; Complex c
6、omplex_add(Complex &c2); /聲明復數(shù)相加函數(shù)聲明復數(shù)相加函數(shù)void display( ); /聲明輸出函數(shù)聲明輸出函數(shù) private:double real; /實部實部double imag; /虛部虛部;Complex Complex complex_add(Complex &c2) Complex c; c.real=real+c2.real; c.imag=imag+c2.imag; return c; void Complex display( ) /定義輸出函數(shù)定義輸出函數(shù) cout(real,imagi)endl; int main(
7、) Complex c1(3,4),c2(5,-10),c3; /定義定義3個復數(shù)對象個復數(shù)對象 c3=plex_add(c2); /調(diào)用復數(shù)相加函數(shù)調(diào)用復數(shù)相加函數(shù) coutc1=; c1.display( ); /輸出輸出c1的值的值 coutc2=; c2.display( ); /輸出輸出c2的值的值 coutc1+c2=; c3.display( ); /輸出輸出c3的值的值 return 0;運行結(jié)果如下:運行結(jié)果如下: c1=(3,4i)c2=(5,-10i)c1+c2=(8,-6i)n結(jié)果是正確的,但調(diào)用方式不直觀、太煩結(jié)果是正確的,但調(diào)用方式不直觀、太煩瑣,不方便。能否也和整
8、數(shù)的加法運算一樣,瑣,不方便。能否也和整數(shù)的加法運算一樣,直接用加號直接用加號“+”來實現(xiàn)復數(shù)運算呢?來實現(xiàn)復數(shù)運算呢?如:如:c3=c1+c2;n如果能做到,就為對象的運算提供了很大如果能做到,就為對象的運算提供了很大的方便。的方便。n這就需要對運算符這就需要對運算符“+”進行重載。進行重載。7.2.1 運算符重載的方法運算符重載的方法定義一個重定義一個重載運算符的函數(shù),在需要執(zhí)行被重載的運算符時,載運算符的函數(shù),在需要執(zhí)行被重載的運算符時,系統(tǒng)就系統(tǒng)就自動自動調(diào)用該函數(shù),以實現(xiàn)相應的運算。調(diào)用該函數(shù),以實現(xiàn)相應的運算。函數(shù)類型函數(shù)類型 operator 運算符名稱運算符名稱 (形參表列形參
9、表列) 對運算符的重載處理對運算符的重載處理 n例如,想將例如,想將“+”用于用于Complex類類(復數(shù)復數(shù))的加法運的加法運算,函數(shù)的原型:算,函數(shù)的原型: Complex operator+ (Complex& c1,Complex& c2); 函數(shù)函數(shù)operator+重載了運算符重載了運算符+。n 用函數(shù)的方法理解運算符用函數(shù)的方法理解運算符:在運算符重載后,執(zhí)行表達式就是調(diào)用在運算符重載后,執(zhí)行表達式就是調(diào)用函數(shù)的過程。函數(shù)的過程??梢园褍蓚€整數(shù)相加也可以把兩個整數(shù)相加也調(diào)用函數(shù):調(diào)用函數(shù): int operator + (int a,int b) return (
10、a+b); 如果有表達式如果有表達式5+8,就調(diào)用此函數(shù),將,就調(diào)用此函數(shù),將5和和8作作為調(diào)用函數(shù)時的實參,函數(shù)的返回值為為調(diào)用函數(shù)時的實參,函數(shù)的返回值為13。(1) C+不允許用戶自己定義新的運算符,不允許用戶自己定義新的運算符,只能對已有的只能對已有的C+運算符進行重載。運算符進行重載。(2) C+中絕大部分的運算符允許重載。不中絕大部分的運算符允許重載。不能重載的運算符只有能重載的運算符只有5個:個: . (成員訪問運算符成員訪問運算符) * (成員指針訪問運算符成員指針訪問運算符) (域運算符域運算符) sizeof (長度運算符長度運算符) ? : (條件運算符條件運算符)前兩個
11、運算符不能重載是為了保前兩個運算符不能重載是為了保證訪問成員的功能不能被改變,證訪問成員的功能不能被改變,域運算符和域運算符和sizeof運算符的運算運算符的運算對象是類型而不是變量或一般表對象是類型而不是變量或一般表達式,不具重載的特征。達式,不具重載的特征。(3) 重載不能改變運算符運算對象重載不能改變運算符運算對象(即操作數(shù)即操作數(shù))的個的個數(shù)。數(shù)。(4) 重載不能改變運算符的優(yōu)先級別。重載不能改變運算符的優(yōu)先級別。(5) 重載不能改變運算符的結(jié)合性。重載不能改變運算符的結(jié)合性。(6) 重載運算符的函數(shù)不能有默認的參數(shù),否則就重載運算符的函數(shù)不能有默認的參數(shù),否則就改變了運算符參數(shù)的個數(shù)
12、,與前面第改變了運算符參數(shù)的個數(shù),與前面第(3)點矛盾。點矛盾。(7) 重載的運算符必須和用戶定義的自定義類型的重載的運算符必須和用戶定義的自定義類型的對象一起使用,其參數(shù)至少應有一個是類對象對象一起使用,其參數(shù)至少應有一個是類對象(或或類對象的引用類對象的引用)。也就是說,參數(shù)不能全部是也就是說,參數(shù)不能全部是C+的標準類型,以防止用戶修改用于標準類型數(shù)據(jù)的標準類型,以防止用戶修改用于標準類型數(shù)據(jù)的運算符的性質(zhì)。的運算符的性質(zhì)。(8) 用于類對象的運算符一般必須重載,但有用于類對象的運算符一般必須重載,但有兩個例外,運算符兩個例外,運算符“=”和和“&”不必用戶重載。不必用戶重載。
13、賦值運算符賦值運算符(=)可以用于每一個類對象,可以利用可以用于每一個類對象,可以利用它在同類對象之間相互賦值。它在同類對象之間相互賦值。 地址運算符地址運算符&也不必重載,它能返回類對象在內(nèi)也不必重載,它能返回類對象在內(nèi)存中的起始地址。存中的起始地址。(9) 應當使重載運算符的功能類似于該運算符應當使重載運算符的功能類似于該運算符作用于標準類型數(shù)據(jù)時所實現(xiàn)的功能。作用于標準類型數(shù)據(jù)時所實現(xiàn)的功能。(10) 運算符重載函數(shù)可以是類的運算符重載函數(shù)可以是類的成員函數(shù)成員函數(shù)(如如例例7.2),也可以是類的,也可以是類的友元函數(shù)友元函數(shù),還可以是既,還可以是既非類的成員函數(shù)也不是友元函數(shù)的
14、普通函數(shù)。非類的成員函數(shù)也不是友元函數(shù)的普通函數(shù)。(1)將運算符重載函數(shù)作為)將運算符重載函數(shù)作為Complex類中類中的成員函數(shù)的成員函數(shù)n 例例7.2 改寫例改寫例7.1,重載運算符,重載運算符“+”,使之,使之能用于兩個復數(shù)相加。能用于兩個復數(shù)相加。class Complexpublic:Complex( )real=0;imag=0;Complex(double r,double i)real=r;imag=i;Complex operator+(Complex &c2); /聲明重載運算符的函數(shù)聲明重載運算符的函數(shù)void display( ); private:double
15、 real;double imag;Complex Complex operator+(Complex &c2) /定義重載運算符的定義重載運算符的函數(shù)函數(shù) Complex c; c.real=real+c2.real; c.imag=imag+c2.imag; return c; void Complex display( ) cout(real,imagi)endl;int main( ) Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; /運算符運算符+用于復數(shù)運算用于復數(shù)運算 coutc1=; c1.display( ); coutc2=; c2.
16、display( ); coutc1+c2=; c3.display( ); return 0;運行結(jié)果與例運行結(jié)果與例7.1相同:相同: c1=(3,4i)c2=(5,-10i)c1+c2=(8,-6i)n在將運算符在將運算符+重載為類的成員函數(shù)后,重載為類的成員函數(shù)后,C+編譯系統(tǒng)將程序中的表達式編譯系統(tǒng)將程序中的表達式c1+c2解釋為:解釋為:c1.operator+(c2) /其中其中c1和和c2是是Complex類的對象類的對象即以即以c2為實參調(diào)用為實參調(diào)用c1的運算符重載函數(shù)的運算符重載函數(shù)operator+(Complex &c2),進行求值,得到兩個,進行求值,得到兩
17、個復數(shù)之和。復數(shù)之和。(2)將運算符重載函數(shù)作為)將運算符重載函數(shù)作為Complex類的類的友元函數(shù)友元函數(shù)n例例7.3 將運算符將運算符“+”重載為適用于復數(shù)加法,重載函數(shù)不重載為適用于復數(shù)加法,重載函數(shù)不作為成員函數(shù),而放在類外,作為作為成員函數(shù),而放在類外,作為Complex類的友元函數(shù)。類的友元函數(shù)。class Complexpublic:Complex( ) real=0;imag=0;Complex(double r,double i) real=r;imag=i;friend Complex operator + (Complex &c1,Complex &c2)
18、;/重載函數(shù)作為友元函數(shù)重載函數(shù)作為友元函數(shù)void display( ); private:double real;double imag;Complex operator + (Complex &c1,Complex &c2) /定義作為友元函數(shù)的重載函數(shù)定義作為友元函數(shù)的重載函數(shù) return Complex(c1.real+c2.real, c1.imag+c2.imag);void Complex display( ) cout(real,imagi)endl;int main( ) Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; co
19、utc1=; c1.display( ); coutc2=; c2.display( ); coutc1+c2 =; c3.display( );n將運算符將運算符“+”重載為非成員函數(shù)后,重載為非成員函數(shù)后,C+編譯系統(tǒng)將程序中的表達式編譯系統(tǒng)將程序中的表達式c1+c2解釋為:解釋為: operator+(c1,c2)n即執(zhí)行即執(zhí)行c1+c2相當于調(diào)用以下函數(shù):相當于調(diào)用以下函數(shù): Complex operator + (Complex &c1,Complex &c2) return Complex(c1.real+c2.real, c1.imag+c2.imag);n單目運
20、算符只有一個操作數(shù),如單目運算符只有一個操作數(shù),如!a,-b,&c,*p,還有最常用的,還有最常用的+i和和-i等。等。n單目運算符只有一個操作數(shù),因此運算符單目運算符只有一個操作數(shù),因此運算符重載函數(shù)只有一個參數(shù),如果運算符重載函重載函數(shù)只有一個參數(shù),如果運算符重載函數(shù)作為成員函數(shù),則還可以省略此參數(shù)。數(shù)作為成員函數(shù),則還可以省略此參數(shù)。n 以自增運算符以自增運算符“+”為例,介紹單目運算為例,介紹單目運算符的重載。符的重載。n例例7.5 有一個有一個Time類,包含數(shù)據(jù)成員類,包含數(shù)據(jù)成員minute(分分)和和sec(秒秒),模擬秒表,每次走一秒,滿,模擬秒表,每次走一秒,滿60
21、秒進一秒進一分鐘,此時秒又從分鐘,此時秒又從0開始算。要求輸出分和秒的值。開始算。要求輸出分和秒的值。#include using namespace std;class Timepublic:Time( )minute=0;sec=0; /默認構(gòu)造函數(shù)默認構(gòu)造函數(shù)Time(int m,int s):minute(m),sec(s) /構(gòu)造函數(shù)重載構(gòu)造函數(shù)重載Time operator+( ); /聲明運算符重載函數(shù)聲明運算符重載函數(shù)void display( )coutminute:sec=60) sec-=60; /滿滿60秒進秒進1分鐘分鐘 +minute; return *this;
22、/返回當前對象值返回當前對象值 int main( ) Time time1(34,0); for (int i=0;i61;i+) +time1; time1.display( ); return 0;運行情況如下:運行情況如下: 34:134:234:5935:035:1 (共輸出共輸出61行行)n例例7.6 在例在例7.5程序的基礎(chǔ)上增加對后置自程序的基礎(chǔ)上增加對后置自增運算符的重載。增運算符的重載。修改后的程序如下:修改后的程序如下:#include using namespace std;class Timepublic: Time( )minute=0;sec=0; Time(in
23、t m,int s):minute(m),sec(s) Time operator+( ); /聲明前置自增運算符聲明前置自增運算符“+”重載函數(shù)重載函數(shù)Time operator+(int); /聲明后置自增運算符聲明后置自增運算符“+”重載函數(shù)重載函數(shù)void display( )coutminute:sec=60) sec-=60; +minute; return *this; /返回自加后的當前對象返回自加后的當前對象Time Time operator+(int) /定義后置自增運算符定義后置自增運算符“+”重載函數(shù)重載函數(shù) Time temp(*this); sec+; if (s
24、ec=60) sec-=60; +minute; return temp; /返回的是自加前的對象返回的是自加前的對象 Time是類名,是類名,temp是是Time類的一個實例,使用了類的一個實例,使用了Time類的拷貝構(gòu)造函數(shù)來類的拷貝構(gòu)造函數(shù)來創(chuàng)建了這個實例,拷貝源是創(chuàng)建了這個實例,拷貝源是當前對象。當前對象。int main( ) Time time1(34,59), time2;cout time1 : ;time1.display( );+time1;cout+time1: ;time1.display( );time2=time1+; /將自加前的對象的值賦給將自加前的對象的值賦給
25、time2couttime1+: ;time1.display( );cout=60) sec-=60; +minute; return *this; p既然是后置自加,返回時就要返回自加前既然是后置自加,返回時就要返回自加前的對象,等操作結(jié)束后才自加,所以,要的對象,等操作結(jié)束后才自加,所以,要通過通過Time temp(*this)在操作之前拷貝,等在操作之前拷貝,等到操作結(jié)束后,返回到操作結(jié)束后,返回temp,而不能是,而不能是*this,因為此時的因為此時的*this已經(jīng)不是已經(jīng)不是temp了,這和前了,這和前置自加是有區(qū)別的。置自加是有區(qū)別的。 n重載后置自增運算符時,多了一個重載后
26、置自增運算符時,多了一個int型的參型的參數(shù),增加這個參數(shù)只是為了與前置自增運算符數(shù),增加這個參數(shù)只是為了與前置自增運算符重載函數(shù)有所區(qū)別,此外沒有任何作用。編譯重載函數(shù)有所區(qū)別,此外沒有任何作用。編譯系統(tǒng)在遇到重載后置自增運算符時,會自動調(diào)系統(tǒng)在遇到重載后置自增運算符時,會自動調(diào)用此函數(shù)。用此函數(shù)。n通過本章前面幾節(jié)的討論,可以看到:通過本章前面幾節(jié)的討論,可以看到:在在 C+中,運算符重載是很重要的、很有實中,運算符重載是很重要的、很有實用意義的。它使類的設計更加豐富多彩,用意義的。它使類的設計更加豐富多彩,擴大了類的功能和使用范圍,使程序易于擴大了類的功能和使用范圍,使程序易于理解,易于
27、對對象進行操作,它體現(xiàn)了為理解,易于對對象進行操作,它體現(xiàn)了為用 戶 著 想 、 方 便 用 戶 使 用 的 思 想 。用 戶 著 想 、 方 便 用 戶 使 用 的 思 想 。n有了運算符重載,在聲明了類之后,人們有了運算符重載,在聲明了類之后,人們就可以像使用標準類型一樣來使用自己聲就可以像使用標準類型一樣來使用自己聲明的類。類的聲明往往是一勞永逸的,有明的類。類的聲明往往是一勞永逸的,有了好的類,用戶在程序中就不必定義許多了好的類,用戶在程序中就不必定義許多成員函數(shù)去完成某些運算和輸入輸出的功成員函數(shù)去完成某些運算和輸入輸出的功能,使主函數(shù)更加簡單易讀。能,使主函數(shù)更加簡單易讀。n好的運
28、算符重載能體現(xiàn)面向?qū)ο蟪绦蛟O計好的運算符重載能體現(xiàn)面向?qū)ο蟪绦蛟O計思想。思想。7.3 虛函數(shù)虛函數(shù) n虛函數(shù)提供了一種更為靈活的多態(tài)性機虛函數(shù)提供了一種更為靈活的多態(tài)性機制。制。n虛函數(shù)允許函數(shù)調(diào)用與函數(shù)體之間的聯(lián)虛函數(shù)允許函數(shù)調(diào)用與函數(shù)體之間的聯(lián)系系在運行時在運行時才建立,也就是在才建立,也就是在運行時才運行時才決定如何動作,決定如何動作,即所謂的即所謂的動態(tài)聯(lián)編動態(tài)聯(lián)編。 面向?qū)ο蠹夹g(shù)中的面向?qū)ο蠹夹g(shù)中的 “后期綁后期綁定定”技術(shù)。技術(shù)??梢栽诨愔卸x一個可以在基類中定義一個虛函數(shù)虛函數(shù),然后在派生類中覆蓋它,然后在派生類中覆蓋它,當調(diào)用此方當調(diào)用此方法時,系統(tǒng)會根據(jù)對象的類型而決定法時
29、,系統(tǒng)會根據(jù)對象的類型而決定調(diào)用哪一個對象的方法(即:不同對調(diào)用哪一個對象的方法(即:不同對象收到相同消息時,產(chǎn)生不同的動象收到相同消息時,產(chǎn)生不同的動作作 )。)。如:如:class fruit virtual void eat()=0; class apple:public fruit void eat() printf(apple eat); class orange:public fruit void eat() printf(orange eat); void fruite_eat(fruit * f) f-eat();例例7.9 虛函數(shù)的引例虛函數(shù)的引例1。#includeclas
30、s Apublic: void show() coutA; ;class B:public A public: void show() coutshow(); pc=&b; pc-show(); return 0; :AA:ABl問題:問題:指向基類對象的指指向基類對象的指針可以指向它的公有派生針可以指向它的公有派生類對象。類對象。但這個對象指針但這個對象指針調(diào)用同名但不同級的成員調(diào)用同名但不同級的成員函數(shù)時會有問題。函數(shù)時會有問題。#includeclass base int a,b;public: base(int x,int y) a=x; b=y; void show( ) c
31、outbase-n; couta bendl;class derived:public baseprivate:int c;public:derived(int x,int y,int z):base(x,y) c=z; void show()coutderived-n;coutc= cshow ();pc=&mc;pc-show ();運行結(jié)果運行結(jié)果:base-60 60base-10 20?沒有指向派生類沒有指向派生類例例7.10 虛函數(shù)的引虛函數(shù)的引例例2錯誤的原因錯誤的原因:C+的的靜態(tài)聯(lián)靜態(tài)聯(lián)編機制編機制。靜態(tài)聯(lián)編首先將指。靜態(tài)聯(lián)編首先將指向基類對象的向基類對象的pc與基類
32、的成與基類的成員函數(shù)員函數(shù)show()連接在一起連接在一起,以后以后不管不管pc再指向哪個對象,再指向哪個對象,pc-show調(diào)用的總是基類調(diào)用的總是基類的成員函數(shù)的成員函數(shù)show()。void main()base mb(60,60),*pc;derived mc(10,20,30);pc=&mb;pc-show ();pc=&mc;pc-show ();void main()/pc=&mb;pc-show ();pc=&mc;pc-show ();mc.show();(derived *)pc)-show();更改獲得預期更改獲得預期結(jié)果的方法結(jié)果的方法b
33、ase-60 60base-10 20derived-c= 30derived-c= 30 n虛函數(shù)同派生類的結(jié)合可使虛函數(shù)同派生類的結(jié)合可使C+支持運支持運行時的多態(tài)性,實現(xiàn)了行時的多態(tài)性,實現(xiàn)了,而而,即常說的即常說的“同一接口,同一接口,多種方法多種方法”,它幫助程序員處理越來越,它幫助程序員處理越來越復雜的程序。復雜的程序。 例例7.11 虛函數(shù)的作用。虛函數(shù)的作用。#includeclass Base public: Base(int x,int y) a=x; b=y; virtual void show() /定義虛函數(shù)定義虛函數(shù)show() coutBase-n; couta
34、bendl; private: int a,b; ;class Derived : public Base public: Derived(int x,int y,int z):Base(x,y)c=z; void show() /重新定義虛函數(shù)重新定義虛函數(shù)show() cout Derived-n; coutcshow(); /調(diào)用基類調(diào)用基類Base的的show()版本版本 pc=&mc; pc-show(); /調(diào)用派生類調(diào)用派生類Derived的的show()版本版本 程序運行結(jié)果如下程序運行結(jié)果如下:Base-60 60Derived-30 結(jié)果正確結(jié)果正確關(guān)鍵字關(guān)鍵字vi
35、rtual指示指示c+編譯器,函編譯器,函數(shù)調(diào)用數(shù)調(diào)用pc-show()在運行時確定調(diào)在運行時確定調(diào)用的函數(shù)用的函數(shù),即對調(diào)用進行,即對調(diào)用進行動態(tài)聯(lián)編動態(tài)聯(lián)編程序在運行時根據(jù)指針程序在運行時根據(jù)指針pc所指向的所指向的實際對象調(diào)用該對象的成員函數(shù)實際對象調(diào)用該對象的成員函數(shù)n定義虛函數(shù)的方法如下定義虛函數(shù)的方法如下: :virtual virtual 函數(shù)類型函數(shù)類型 函數(shù)名函數(shù)名( (形參表形參表) ) / / 函數(shù)體函數(shù)體 n對虛函數(shù)的定義的幾點說明:對虛函數(shù)的定義的幾點說明:通過定義虛函數(shù)使用通過定義虛函數(shù)使用C+提供的多態(tài)性機制提供的多態(tài)性機制時,派生類應從其時,派生類應從其必須首先
36、在基類中定義為虛函數(shù);必須首先在基類中定義為虛函數(shù);C+規(guī)定,規(guī)定,。因此,派生類中的因此,派生類中的virtual可寫可不寫,可寫可不寫,為避免混亂,最好在派生類的虛函數(shù)進行重為避免混亂,最好在派生類的虛函數(shù)進行重新定義時加上關(guān)鍵字新定義時加上關(guān)鍵字virtual。 一個虛函數(shù)無論被公有繼承多少次,仍保持一個虛函數(shù)無論被公有繼承多少次,仍保持其虛函數(shù)特性。其虛函數(shù)特性。虛函數(shù)必須是類的成員函數(shù)虛函數(shù)必須是類的成員函數(shù),不能是友員函,不能是友員函數(shù),也不能是靜態(tài)成員函數(shù)。數(shù),也不能是靜態(tài)成員函數(shù)。內(nèi)聯(lián)函數(shù)不能是虛函數(shù)內(nèi)聯(lián)函數(shù)不能是虛函數(shù),因為內(nèi)聯(lián)函數(shù)是在,因為內(nèi)聯(lián)函數(shù)是在編譯時確定位置。虛函數(shù)
37、雖然定義在類內(nèi)部,編譯時確定位置。虛函數(shù)雖然定義在類內(nèi)部,但編譯時仍將其視為非內(nèi)聯(lián)。但編譯時仍將其視為非內(nèi)聯(lián)。構(gòu)造函數(shù)不能是虛函數(shù)構(gòu)造函數(shù)不能是虛函數(shù),因為虛函數(shù)作為運,因為虛函數(shù)作為運行過程中多態(tài)的基礎(chǔ),主要是針對對象的,行過程中多態(tài)的基礎(chǔ),主要是針對對象的,而構(gòu)造函數(shù)是在對象產(chǎn)生之前運行的,因此而構(gòu)造函數(shù)是在對象產(chǎn)生之前運行的,因此虛構(gòu)造函數(shù)無意義。虛構(gòu)造函數(shù)無意義。析構(gòu)函數(shù)可以是虛函數(shù)。析構(gòu)函數(shù)可以是虛函數(shù)。7.4 純虛函數(shù)和抽象類純虛函數(shù)和抽象類 n純虛函數(shù)純虛函數(shù)(pure virtual function)是一個在是一個在基類中說明的虛函數(shù),它在該基類中說明的虛函數(shù),它在該基類中沒基類中沒有定義有定義,但要求,但要求在它的派生類中必須定在它的派生類中必須定義自己的版本,或重新說明為純虛函數(shù)。義自己的版本,或重新說明為純虛函數(shù)。n純虛函數(shù)的定義形式如下純虛函數(shù)的定義形式如下: virtual 函數(shù)類型函數(shù)類型 函數(shù)名函數(shù)名(參數(shù)表參數(shù)表)=0; 注意:注意:n純虛函數(shù)沒有函數(shù)體;純虛函數(shù)沒有函數(shù)體;n最后面的最后面的“=0”并不表示函數(shù)返回值為并不表示函數(shù)返回
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 25246-2025畜禽糞肥還田技術(shù)規(guī)范
- 2025年常德c1貨運從業(yè)資格證考試內(nèi)容
- 兒童桌子采購合同范本
- 鄉(xiāng)鎮(zhèn)飯店轉(zhuǎn)讓合同范本
- 公司房租轉(zhuǎn)租合同范本
- 倉庫裝修合同范本版
- 上海廠房出售合同范本
- 茶器定制合同范本
- 中標咨詢合同范本
- 農(nóng)村訂購混泥土合同范本
- 2023年中國農(nóng)業(yè)大學人才招聘筆試真題
- GB/T 44619-2024福壽螺檢疫鑒定方法
- 2024年湖南省公務員錄用考試《行測》試題及答案解析
- 北京聯(lián)合大學《電子技術(shù)基礎(chǔ)》2022-2023學年期末試卷
- 電力工程質(zhì)量驗收手冊
- 四年級語文下冊 期末復習文言文閱讀專項訓練(一)(含答案)(部編版)
- 學習新課程標準的方案
- 2024年知識競賽-煙花爆竹安全管理知識競賽考試近5年真題附答案
- 民航基礎(chǔ)知識應用題庫100道及答案解析
- 2024年黑龍江省哈爾濱市中考數(shù)學試卷(附答案)
- SolidWorks-2020項目教程全套課件配套課件完整版電子教案
評論
0/150
提交評論