第4章面向?qū)ο蟪绦蛟O(shè)計(jì)課件_第1頁
第4章面向?qū)ο蟪绦蛟O(shè)計(jì)課件_第2頁
第4章面向?qū)ο蟪绦蛟O(shè)計(jì)課件_第3頁
第4章面向?qū)ο蟪绦蛟O(shè)計(jì)課件_第4頁
第4章面向?qū)ο蟪绦蛟O(shè)計(jì)課件_第5頁
已閱讀5頁,還剩47頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、知識要點(diǎn): 1 1 多態(tài)性概述多態(tài)性概述-“領(lǐng)會領(lǐng)會”的層次。的層次。 2 2 運(yùn)算符重載運(yùn)算符重載-“簡單應(yīng)用簡單應(yīng)用”的層次。的層次。 3 3 虛函數(shù)虛函數(shù)-“簡單應(yīng)用簡單應(yīng)用”的層次。的層次。 4 4 抽象類抽象類-“簡單應(yīng)用簡單應(yīng)用”的層次。的層次。4.1多態(tài)性概述4.1多態(tài)性概述 多態(tài)是指同樣的消息被不同類型的對象接收后導(dǎo)致完全不同的行為,消息是指對類的成員函數(shù)的調(diào)用,不同的行為是指不同的實(shí)現(xiàn),也就是調(diào)用了不同的函數(shù)。4.1.1 多態(tài)的類型面向?qū)ο蟮亩鄳B(tài)性可以分為4類:重載多態(tài)、強(qiáng)制多態(tài)、包含多態(tài)和參數(shù)多態(tài)。前面兩種統(tǒng)稱為專用多態(tài),而后面兩種也稱為通用多態(tài)。重載多態(tài),普通函數(shù)及類的成

2、員函數(shù)的重載。強(qiáng)制多態(tài)是指將一個(gè)變元的類型加以變化,以符合一個(gè)函數(shù)或者操作的要求。如把整型數(shù)變?yōu)楦↑c(diǎn)數(shù)再相加的情況,就是強(qiáng)制多態(tài)的實(shí)例包含多態(tài)包含多態(tài)是研究類族中定義于不同類中的同名成員函數(shù)的多態(tài)行為,主要是通過虛函數(shù)來實(shí)現(xiàn)。參數(shù)多態(tài)與類模板(類屬)相關(guān)聯(lián),在后面章節(jié)中介紹的類模板是一個(gè)參數(shù)化的模板,在使用時(shí)必須賦予實(shí)際的類型才可以實(shí)例化。 4.1多態(tài)性概述4.1.2 多態(tài)的實(shí)現(xiàn)多態(tài)從實(shí)現(xiàn)的角度來講可以劃分為兩類:編譯時(shí)的多態(tài)和運(yùn)行時(shí)的多態(tài)。前者是在編譯的過程中確定了同名操作的具體操作對象,而后者則是在程序運(yùn)行過程中才動態(tài)地確定操作所針對的具體對象。確定操作的具體對象的過程就是聯(lián)編(bindi

3、ng)。聯(lián)編是指計(jì)算機(jī)程序自身彼此關(guān)聯(lián)的過程,也就是把一個(gè)標(biāo)識符名和一個(gè)存儲地址聯(lián)系在一起的過程;用面向?qū)ο蟮男g(shù)語講,就是把一條消息和一個(gè)對象的方法相結(jié)合的過程。按照聯(lián)編進(jìn)行的階段的不同,分為兩種不同的聯(lián)編方法:靜態(tài)聯(lián)編和動態(tài)聯(lián)編。 聯(lián)編工作在編譯連接階段完成的情況稱為靜態(tài)聯(lián)編,比如重載、強(qiáng)制和參數(shù)多態(tài) 聯(lián)編工作在程序運(yùn)行階段完成的情況稱為動態(tài)聯(lián)編,也稱為晚期聯(lián)編或后聯(lián)編,如包含多態(tài)。4.2 運(yùn)算符重載【案例】運(yùn)算符重載在計(jì)算器程序中的應(yīng)用【案例需求】:設(shè)計(jì)一個(gè)控制臺計(jì)算器程序,實(shí)現(xiàn)輸入任意數(shù)學(xué)表達(dá)式都能進(jìn)行數(shù)學(xué)計(jì)算,運(yùn)算包括加、減、乘、除,可以帶括號,還可包含數(shù)學(xué)中復(fù)數(shù)的計(jì)算【案例說明】:

4、本案例中涉及到多個(gè)問題或任務(wù)的實(shí)現(xiàn),首先考慮的是輸入的是一個(gè)表達(dá)式字符串,可以帶括號,這里需要將表達(dá)式分割成相應(yīng)的運(yùn)算的操作數(shù)和運(yùn)算符分別放入相應(yīng)棧中,并根據(jù)運(yùn)算符的優(yōu)先級進(jìn)行計(jì)算。這個(gè)問題在數(shù)據(jù)結(jié)構(gòu)中似乎可以得到解決。 其次,在分割過程中遇到了在分割過程中遇到了1+2i的數(shù)據(jù)類型的數(shù)據(jù)類型,這里是復(fù)數(shù),需要定義復(fù)數(shù)類,那么簡單的基本數(shù)據(jù)可以進(jìn)行可以直接用+進(jìn)行相加,如X=1+2,但是復(fù)數(shù)在C+中不是基礎(chǔ)數(shù)據(jù)類型,需要我們自己定義復(fù)數(shù)類,復(fù)數(shù)對象,使M3=M1+M2;如果程序中也能用+號進(jìn)行復(fù)數(shù)相加得到的還是復(fù)數(shù),那么是否可以直接相加形成上述程序表達(dá)式呢? 用傳統(tǒng)的運(yùn)算符進(jìn)行參與表達(dá)式計(jì)算,需

5、要對運(yùn)算符的功能進(jìn)行重新定義,使之具備也能操作新的數(shù)據(jù)類型的能力,我們稱之為運(yùn)算符重載。4.2 運(yùn)算符重載#includeclass complex /復(fù)數(shù)類 float real, imag; public: complex(float r=0,float i=0) real=r; imag=i; void show() coutreal+imagi“endl; ;void main() complex x(5,2); complex y(4,3); complex z; z=x+y; /該賦值表達(dá)式編譯錯(cuò)誤,該賦值表達(dá)式編譯錯(cuò)誤,+不能實(shí)現(xiàn)兩類對象相加再傳給對象不能實(shí)現(xiàn)兩類對象相加再傳給對

6、象 z.show();4.2 運(yùn)算符重載采用的方法:在complex類里添加一個(gè)成員函數(shù)Add,如下代碼所示:complex complex: add( complex c) complex temp; temp.real=real+c.real; temp.imag=imag+c.imag; return temp; 在main函數(shù)中只要將z=x+y;改成z=x.add(y),但這樣的代碼在形式上不如z=x+y顯得直接簡單,C +已經(jīng)提供了具備運(yùn)算符重載的功能,實(shí)際上這些運(yùn)算符本質(zhì)上即是函數(shù)構(gòu)成。 對于表達(dá)式x=5+7來說,編譯器在處理它時(shí),并不知道符號“+”表示什么意思,它可以將這個(gè)表達(dá)式

7、解釋成函數(shù)調(diào)用的形式:x=operator+(5,7) 調(diào)用的函數(shù)原型如下所示: int operator+(int a,int b) return a+b; void main() complex x(5,2); complex y(4,3); complex z; z=x.add(y); / z=x+y; z.show(); 類似于函數(shù)add(5,7)所完成的功能4.2 運(yùn)算符重載 operator+(5,7)的這種調(diào)用形式和普通的函數(shù)調(diào)用還是不同的,一般稱之為運(yùn)算符重載,也可以說C+的一種特殊調(diào)用形式。 在C+中,operator是關(guān)鍵字,它經(jīng)常和C+中的一個(gè)運(yùn)算符聯(lián)用,表示一個(gè)運(yùn)算符函

8、數(shù)名,也稱重載運(yùn)算符函數(shù)。重載運(yùn)算符函數(shù)可以完成和運(yùn)算符同樣的功能,但功能更強(qiáng)。運(yùn)算符重載是通過重載函數(shù)來完成的。 在復(fù)數(shù)類中增加一個(gè)成員函數(shù),再用原來的測試代碼即可實(shí)現(xiàn)兩復(fù)數(shù)相加complex operator+(complex &c) float r,i; r=real+c.real; i=imag+c.imag; return complex(r,i); 此時(shí)z=x+y;表達(dá)式被C+編譯器編譯成z=x.operator+(y); 形式上和z=x.add(y)類似complex complex: add( complex c) complex temp; temp.real=rea

9、l+c.real; temp.imag=imag+c.imag; return temp; 4.2 運(yùn)算符重載4.2.1 運(yùn)算符重載的規(guī)則運(yùn)算符重載的規(guī)則1運(yùn)算符重載函數(shù)的定義 要重載一個(gè)操作符必須用一個(gè)函數(shù)形式對它重新定義,用關(guān)鍵字operator后跟這個(gè)操作符的符號作為重載函數(shù)名。該函數(shù)的一般形式如下: 類型類型 類名類名:operator#(參數(shù)表參數(shù)表) /相對于該類而定義的操作相對于該類而定義的操作 通過類對象操作重載運(yùn)算符,要求能訪問這個(gè)類的私有成員,故運(yùn)算符重載函數(shù)必須是它們所用于的類的成員函數(shù)或友元函數(shù)。重載函數(shù)名是由operator和運(yùn)算符組成。operator是關(guān)鍵字,是專

10、門用于定義重載運(yùn)算符的函數(shù)的,運(yùn)算符名稱就是提供給用戶的預(yù)定義運(yùn)算符。operator+就是函數(shù)名,意思是“對運(yùn)算符+重載”。兩個(gè)形參是Complex類對象的引用,要求實(shí)參為Complex類對象。在定義了重載運(yùn)算符的函數(shù)后,函數(shù)operator+重載了運(yùn)算符+。4.2 運(yùn)算符重載2重載運(yùn)算符函數(shù)的操作數(shù)個(gè)數(shù)重載運(yùn)算符與重載一般函數(shù)的區(qū)別主要是在參數(shù)的個(gè)數(shù)上。C+的運(yùn)算符所能操作的操作數(shù)的個(gè)數(shù)事先是規(guī)定好的. 雙目運(yùn)算符對兩個(gè)操作數(shù)進(jìn)行運(yùn)算,單目運(yùn)算符對一個(gè)操作數(shù)進(jìn)行運(yùn)算。 重載單目運(yùn)算符時(shí),只能指定一個(gè)參數(shù),而重載雙目運(yùn)算符時(shí),只能指定兩個(gè)參數(shù)。根據(jù)不同的運(yùn)算符重載可以定義為類的成員函數(shù),也可

11、以定義為類的友員函數(shù),同一種運(yùn)算符又可能有不同的放置位置,如+,-,有前置+,后置+,其在運(yùn)算符重載函數(shù)定義的形式上又有所區(qū)別。以復(fù)數(shù)相加,和時(shí)鐘類對象自加為例說明。4.2 運(yùn)算符重載1. 雙目運(yùn)算符(如+)作為類成員函數(shù)重載#includeclass complex /復(fù)數(shù)類 float real,imag; public: complex(float r=0,float i=0) real=r; imag=i; complex operator+(complex c); void show() coutreal+iimagendl; ;complex complex:operator+(c

12、omplex c) complex temp;temp.real=real+c.real;temp.imag=imag+c.imag;return temp;調(diào)用: complex a(1,1),b(2,2), c; c=a+b; /編譯成c=a.operator+(b); 雙目運(yùn)算符重載函數(shù)作為類成員,只有雙目運(yùn)算符重載函數(shù)作為類成員,只有一個(gè)參數(shù)一個(gè)參數(shù)作為操作數(shù),另一個(gè)操作作為操作數(shù),另一個(gè)操作數(shù)作為數(shù)作為this對象調(diào)用該函數(shù)并參與運(yùn)算。對象調(diào)用該函數(shù)并參與運(yùn)算。4.2 運(yùn)算符重載2. 雙目運(yùn)算符(如+)作為友員函數(shù)重載#includeclass complex /復(fù)數(shù)類 float

13、real,imag; public: complex(float r=0,float i=0) real=r; imag=i; friend complex operator+(complex a, complex b); void show() coutreal+iimagendl; ;complex operator+(complex a, complex b) complex temp; temp.real=a.real+b.real; temp.imag=a.imag+b.imag; return temp;調(diào)用:complex a(1,1),b(2,2),c;c=a+b; /編譯成c

14、= operator+(a, b);雙目運(yùn)算符重載函數(shù)作為雙目運(yùn)算符重載函數(shù)作為友員友員函數(shù)函數(shù),有,有2個(gè)參數(shù)個(gè)參數(shù)作為操作數(shù)。作為操作數(shù)。4.2 運(yùn)算符重載3.單目運(yùn)算符(如+)作為類成員函數(shù)(前置)重載class Clock /時(shí)間類,其對象就是一時(shí)間 int h,m,s; public: Clock(int a=0,int b=0,int c=0)h=a;m=b;s=c; void show() couth”:”m”:”s; operator+(); /(前置(前置+)重載)重載 operator+(int); / (后置(后置+)重載)重載;Clock Clock:operator+

15、() /秒加1 /返回加過1秒的時(shí)間;調(diào)用:Clock c1(23,59,59),c2;c2=+c1; /編譯成c2=c1.operator+()c2.show(); /顯示0:0:04.2 運(yùn)算符重載4 單目運(yùn)算符(如+)作為類成員函數(shù)(后置)重載Clock Clock:operator+(int) 構(gòu)造臨時(shí)時(shí)間保存當(dāng)前時(shí)間 當(dāng)前時(shí)間的秒加1 返回臨時(shí)時(shí)間;調(diào)用:Clock c1(23,59,59),c2;c2=c1+; /編譯成c2=c1.operator+(0)c2.show(); /顯示23:59:594.2 運(yùn)算符重載5.單目運(yùn)算符(如+)作為友員函數(shù)(前置)重載class Cloc

16、k /時(shí)間類,其對象就是一時(shí)間 int h,m,s; public: Clock(int a=0,int b=0,int c=0) h=a;m=b;s=c; void show() couth”:”m”:”s; friend Clock operator+( Clock &c);/(前置(前置+)重載)重載 friend Clock operator+( Clock &c, int); / (后置(后置+)重載)重載;Clock operator+( Clock &c) 秒加1 返回加過1秒的時(shí)間;調(diào)用:c1(23,59,59),c2;c2=+c1; /編譯成c2=op

17、erator+(c1)c2.show(); /顯示0:0:04.2 運(yùn)算符重載6 單目運(yùn)算符(如+)作為友員函數(shù)(后置)重載Clock operator+( Clock &c, int x) 構(gòu)造臨時(shí)時(shí)間保存當(dāng)前時(shí)間 當(dāng)前時(shí)間的秒加1 返回臨時(shí)時(shí)間;調(diào)用:c1(23,59,59),c2;c2=c1+; /編譯成c2= operator+(c1,0)c2.show(); /顯示23:59:594.2 運(yùn)算符重載3C+對運(yùn)算符重載也有一些限制不能更改任何運(yùn)算符的優(yōu)先級和結(jié)合性;不可改變此運(yùn)算符所需要的操作數(shù)的數(shù)目;只可以對已有的運(yùn)算符進(jìn)行重載,不可臆造新的運(yùn)算符。用于類對象的運(yùn)算符一般必須

18、重載,但有兩個(gè)例外,運(yùn)算符“=”和“&”不必用戶重載。賦值運(yùn)算符(=)可以用于每一個(gè)類對象,可以利用它在同類對象之間相互賦值。地址運(yùn)算符&也不必重載,它能返回類對象在內(nèi)存中的起始地址。應(yīng)當(dāng)使重載運(yùn)算符的功能類似于該運(yùn)算符作用于標(biāo)準(zhǔn)類型數(shù)據(jù)時(shí)所實(shí)現(xiàn)的功能。運(yùn)算符重載函數(shù)可以是類的成員函數(shù),也可以是類的友元函數(shù),還可以是既非類的成員函數(shù)也不是友元函數(shù)的普通函數(shù)。重載運(yùn)算符含義必須清楚。下列運(yùn)算符是不能重載的:“.” 成員訪問運(yùn)算符“.*” 成員指針訪問運(yùn)算符“:” 域運(yùn)算符“?:” 條件運(yùn)算符“sizeof()” 數(shù)據(jù)長度運(yùn)算符4.2 運(yùn)算符重載4.2.2 運(yùn)算符重載為成員函數(shù) 運(yùn)

19、算符重載為類的成員函數(shù),即該函數(shù)屬于該類的操作。它就可以自由地訪問本類的數(shù)據(jù)成員。實(shí)際使用時(shí),是通過該類的某個(gè)對象來訪問重載的運(yùn)算符。 如果是雙目運(yùn)算符,一個(gè)操作數(shù)是對象本身的數(shù)據(jù),由this指針指出,另一個(gè)操作數(shù)則需要通過運(yùn)算符重載函數(shù)的參數(shù)表來傳遞; 如果是單目運(yùn)算符,操作數(shù)由對象的this指針給出,就不再需要任何參數(shù)。1. 雙目運(yùn)算符作為類成員重載 雙目運(yùn)算符(或稱二元運(yùn)算符)是最常用的運(yùn)算符。雙目運(yùn)算符有兩個(gè)操作數(shù),通常在運(yùn)算符的左右兩側(cè),如3+5,a/b,i10等。 在重載雙目運(yùn)算符時(shí),在函數(shù)中應(yīng)該有兩個(gè)參數(shù)。4.2 運(yùn)算符重載【程序4-2】 定義一個(gè)字符串類String,用來存放不

20、定長的字符串,重載運(yùn)算符“=”, “”,用于兩個(gè)字符串的等于、小于和大于的比較運(yùn)算。(1)先建立一個(gè)String類:#include using namespace std;class String /String 是用戶自己指定的類名 public: String()p=NULL; /默認(rèn)構(gòu)造函數(shù) String(char *str); /構(gòu)造函數(shù) void display(); private: char *p; /字符型指針,用于指向字符串;String:String(char *str) /定義構(gòu)造函數(shù) p=str; /使P指向?qū)崊⒆址畍oid String:display() /輸出

21、p所指向的字符串 coutp”friend bool operator(String &string1,String &string2); /聲明運(yùn)算符函數(shù)為友元函數(shù)friend bool operator(String &string1,String &string2) /定義運(yùn)算符重載函數(shù) if(strcmp(string1.p,string2.p)0) return true; else return false; int main() String string1(Hello),string2(Book); coutstring2)(String &am

22、p;string1,String &string2) /對運(yùn)算符”重載 if(strcmp(string1.p, string2.P)0) return true; else return false; bool operator(String &stringl,String &string2) /對運(yùn)算符“”重載 if(strcmp(stringl.p, stuns2.p)0) return true; else return false; bool operator=(String &string1,String &string2) /對運(yùn)算符“=”

23、重載 if(strcmp(stfingl.p,stfing2.p)=0) return true; else return false; 再修改主函數(shù): int main() String string1(“Hello”), string2(“Book”), stnng3(Computer); coutstrlng2)endl; /比較結(jié)果應(yīng)該為true cout(string1string3)endl; /比較結(jié)果應(yīng)該為false cout(string1=string2)string2)=1) string1.display(); cout; string2.display(); else

24、 if(string1string2)=1) string1.display(); cout; string2.display(); else if(string1=string2)=1) string1.display(); cout=; string2.display(); coutendl; int main() String string1(Hello),string2(Book),string3(Computer),string4(Hello); compare(string1,string2); compare(string2,string3); compare(string1,s

25、tring4); return 0; 4.2 運(yùn)算符重載2.單目運(yùn)算符作為類成員重載 單目運(yùn)算符只有一個(gè)操作數(shù),如!a,-b,&c,*p,還有常用的+i和-i等。 重載單目運(yùn)算符的方法與重載雙目運(yùn)算符的方法是類似的。但由于單目運(yùn)算符只有一個(gè)操作數(shù),因此運(yùn)算符重載函數(shù)只有一個(gè)參數(shù),如果運(yùn)算符重載函數(shù)作為成員函數(shù),則還可省略此參數(shù)。以自增運(yùn)算符“+”為例,介紹單目運(yùn)算符的重載?!境绦?-3】有一個(gè)Clock類,包含數(shù)據(jù)成員minute(分)和sec(秒),模擬秒表,每次走一秒,滿60秒進(jìn)一分鐘,此時(shí)秒又從頭開始算。要求輸出分和秒的值。4.2 運(yùn)算符重載#include using name

26、space std;class Clock public: Clock()minute=0;sec=0; /默認(rèn)構(gòu)造函數(shù) Clock(int m,int s):minute(m),sec(s) /構(gòu)造函數(shù)重載 Clock operator+(); /聲明運(yùn)算符重載函數(shù) void display()coutminute“:”sec=60) sec-=60; /滿60秒進(jìn)1分鐘 +minute; return *this; /返回當(dāng)前對象值 int main() Clock Clock1(34,0); for (int i=0;i61;i+) +Clock1; Clock1.display();

27、return 0; Clock(minute, sec)4.2 運(yùn)算符重載 針對“+”和“-”的運(yùn)算 ,C+約定:如果在自增(自減)運(yùn)算符重載函數(shù)中,增加一個(gè)int型形參,就是后置自增(自減)運(yùn)算符函數(shù)?!境绦?-4】對后置自增運(yùn)算符的重載class Clock public: Clock()minute=0;sec=0; Clock(int m,int s):minute(m),sec(s) Clock operator+(); /聲明前置白增運(yùn)算符“+”重載函數(shù) Clock operator+(int); /聲明后置自增運(yùn)算符“+”重載函數(shù) void display()coutminute

28、:sec=60) sec-=60; +minute; return temp; 重載后置自增運(yùn)算符時(shí),多了一個(gè)重載后置自增運(yùn)算符時(shí),多了一個(gè)int型的參型的參數(shù),為了與前置自增運(yùn)算符重載函數(shù)有所區(qū)數(shù),為了與前置自增運(yùn)算符重載函數(shù)有所區(qū)別,此外沒有任何作用別,此外沒有任何作用。 在定義函數(shù)時(shí)也不必使用此參數(shù),可省寫參在定義函數(shù)時(shí)也不必使用此參數(shù),可省寫參數(shù)名,只需在括號中寫數(shù)名,只需在括號中寫int即可。編譯系統(tǒng)在即可。編譯系統(tǒng)在遇到重載后置自增運(yùn)算符時(shí),會自動調(diào)用此遇到重載后置自增運(yùn)算符時(shí),會自動調(diào)用此函數(shù)函數(shù)。4.2 運(yùn)算符重載int main() Clock Clock1(34,59),C

29、lock2; cout Clock1 : ; Clock1.display(); +Clock1; cout+Clock1: ; Clock1.display(); Clock2=Clock1+; /將自加前的對象的值賦給Clock2 coutClock1+: ; Clock1.display(); cout Clock2 : ; /輸出Clock2對象的值 Clock2.display(); return 0; 4.2 運(yùn)算符重載4.2.3 運(yùn)算符重載為友元函數(shù)運(yùn)算符重載為友元函數(shù)將運(yùn)算符函數(shù)不作為成員函數(shù),而把它放在類外,在Complex類中聲明它為友元函數(shù)。將運(yùn)算符重載為類的友元函數(shù),就

30、必須把操作數(shù)全部通過形參的方式傳遞給運(yùn)算符重載函數(shù)。一般將單目運(yùn)算符重載為成員函數(shù),將雙目運(yùn)算符重載為友元函數(shù)規(guī)定: 運(yùn)算符(如賦值運(yùn)算符=、下標(biāo)運(yùn)算符 、函數(shù)調(diào)用運(yùn)算符)必須定義為類的成員函數(shù)。 流插入“”、類型轉(zhuǎn)換運(yùn)算符運(yùn)算符則不能定義為類的成員函數(shù)()?!境绦?-5】 復(fù)數(shù)類加減法運(yùn)算重載友元函數(shù)形式。4.2 運(yùn)算符重載【程序4-5】 復(fù)數(shù)類加減法運(yùn)算重載友元函數(shù)形式#includeclass complex /復(fù)數(shù)類聲明 public: complex(double r=0.0,double i=0.0) real=r; imag=i; /構(gòu)造函數(shù) friend complex ope

31、rator+(complex c1,complex c2); /運(yùn)算符+重載友元函數(shù) friend complex operator-(complex c1,complex c2); /運(yùn)算符-重載友元函數(shù) void display( ); /顯示復(fù)數(shù)的值 private: /私有數(shù)據(jù)成員 double real; double imag;4.2 運(yùn)算符重載void complex:display( )/顯示函數(shù)實(shí)現(xiàn) cout(real,imag)endl; complex operator+(complex c1,complex c2) /運(yùn)算符重載友元函數(shù)實(shí)現(xiàn) return complex

32、(c2.real+c1.real,c2.imag+c1.imag); complex operator-(complex c1,complex c2) /運(yùn)算符重載友元函數(shù)實(shí)現(xiàn) return complex(c1.real-c2.real,c1.imag-c2.imag);void main( ) complex c1(5,4),c2(2,10),c3; coutc1=;c1.display( ); coutc2=;c2.display( ); c3=c1-c2; /使用重載運(yùn)算符 coutc3=c1-c2=; c3.display( ); c3=c1+c2; /使用重載運(yùn)算符 coutc3=

33、c1+c2=; c3.display( );4.2 運(yùn)算符重載4.2.3 重載插入和提取運(yùn)算符重載插入和提取運(yùn)算符C+的流插入運(yùn)算符“”是在類庫中提供的,所有編譯系統(tǒng)都在類庫中提供輸入流類istream和輸出流類ostream。cin和cout分別是istream類和ostream類的對象。用“cout ”對標(biāo)準(zhǔn)類型數(shù)據(jù)進(jìn)行輸入輸出的,都要用#include把頭文件包含到本程序文件中。用戶自己定義的類型的數(shù)據(jù),是不能直接用“”來輸出和輸入的。用它們輸出和輸入自己聲明的類型的數(shù)據(jù),必須對它們重載。4.2 運(yùn)算符重載 對“”重載的函數(shù)形式如下: istream &operator(istr

34、eam&,自定義類,自定義類&); ostream &operator”的函數(shù)的第一個(gè)參數(shù)和函數(shù)的類別都必須是istream&類型,第二個(gè)參數(shù)是要進(jìn)行輸入操作的類。 重載“和“”的函數(shù)作為友元函數(shù)或普通作為友元函數(shù)或普通的函數(shù)的函數(shù),而不能將它們定義為成員函數(shù)。【程序4-6】 在程序4-5的基礎(chǔ)上,用重載的“”輸出復(fù)數(shù)4.2 運(yùn)算符重載#includeclass Complex public: Complex() real=0;imag=0; Complex(double r, double i)real=r;imag=i; Complex operator +

35、 (Complex &c2); /運(yùn)算符“+”重載為成員函數(shù) friend ostream& operator (ostream&,Complex&); /運(yùn)算符“”重載為友元函數(shù) private: double real; double imag; ;4.2 運(yùn)算符重載Complex Complex:operator + (Complex &c2) /定義運(yùn)算符“+”重載函數(shù) return Complex(real+c2.real,imag+c2.imag); ostream& operator (ostream &output, Co

36、mplex &c) /定義運(yùn)算符“”重載函數(shù) output(c.real+c.imagi)endl; return output; / output是cout的別名,ostream類的對象引用 int main() Complex c1(2,4),c2(6,10),c3; c3=c1+c2; coutc3; / c3不是基本數(shù)據(jù)類型,是類對象,只有把”的作用是從一個(gè)輸入流中提取數(shù)據(jù),如cini;表示從輸入流中提取一個(gè)整數(shù)賦給變量i(假設(shè)已定義i為int型)。 重載流提取運(yùn)算符的目的是將“”用于輸入自定義類型的對象的信息?!境绦?-7】增加重載流提取運(yùn)算符“”,用cin輸入復(fù)數(shù),cout

37、輸出復(fù)數(shù)。 ostream& operator (ostream& output,Complex& c) /定義重載運(yùn)算符“”函數(shù) output(c.real+c.imag (istream &input, Complex &c) /定義重載運(yùn)算符“”函數(shù) coutc.realc.imag; return input; int main() Complex c1,c2; cinc1c2; /一次調(diào)用一次重載函數(shù) coutc1=c1endl; coutc2=c2endl; return 0; 運(yùn)算符重載小結(jié) 運(yùn)算符重載是通過定義重載函數(shù)實(shí)現(xiàn)的。 函數(shù)的一般

38、形式如下: 類型類型 類名類名:operator # (參數(shù)表參數(shù)表) /相對于該類而定義的操作相對于該類而定義的操作 運(yùn)算符重載函數(shù)必須是類的成員函數(shù)或友元函數(shù),要求能訪問這個(gè)類的私有成員。 引用時(shí)要求實(shí)參為類對象。 C+的運(yùn)算符所能操作的操作數(shù)的個(gè)數(shù)事先是規(guī)定好的:雙目運(yùn)算符對兩個(gè)操作數(shù)進(jìn)行運(yùn)算,單目運(yùn)算符對一個(gè)操作數(shù)進(jìn)行運(yùn)算。 雙目運(yùn)算符重載函數(shù)作為類成員函數(shù),只有一個(gè)參數(shù)作為操作數(shù),另一個(gè)操作數(shù)作為this對象調(diào)用該函數(shù)并參與運(yùn)算。complex complex:operator+(complex c)雙目運(yùn)算符重載函數(shù)作為友員函數(shù),有2個(gè)參數(shù)作為操作數(shù)。complex operato

39、r+(complex a, complex b)基本運(yùn)算符形參是類對象的引用練習(xí):練習(xí): 編寫程序:定義一個(gè)復(fù)數(shù)類,重載運(yùn)算符“+”,“-”用于復(fù)數(shù)的加減運(yùn)算,將運(yùn)算符重載函數(shù)作為類的成員函數(shù),分別求復(fù)數(shù)的加、減法運(yùn)算 。4.3 虛函數(shù)虛函數(shù) 多態(tài)性是指具有不同功能的函數(shù)可以用同一個(gè)函數(shù)名,可以用一個(gè)函數(shù)名調(diào)用不同內(nèi)容的函數(shù)。 多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計(jì)的一個(gè)重要特征,多態(tài)性可以設(shè)計(jì)和實(shí)現(xiàn)一個(gè)易于擴(kuò)展的系統(tǒng)。 當(dāng)一個(gè)基類被繼承為不同的派生類時(shí),各派生類可以使用與基類成員相同的成員名,如果在運(yùn)行時(shí)用同一個(gè)類對象調(diào)用的成員函數(shù),會調(diào)用哪個(gè)對象的成員? 通過繼承而產(chǎn)生了相關(guān)的不同的派生類,與基類成員同

40、名的成員在不同的派生類中有不同的含義。也可以說,多態(tài)性是“一個(gè)接口,多種方法”?!境绦?-8】#include #include using namespace std;class CBase public: void show() cout BASE endl; ;class CDerive : public CBase public: void show() cout DERIVE endl; ;int main ( ) CDerive d; Cbase &x=d; d.show(); x.show(); return 0;4.3 虛函數(shù)虛函數(shù)4.3.1 一般虛函數(shù)一般虛函數(shù)用一個(gè)

41、調(diào)用形式,既能調(diào)用派生類的函數(shù)又能調(diào)用基類的同名函數(shù)。不通過不同的對象名去調(diào)用不同派生層次中的同名函數(shù)。 例: d.show(); 可以調(diào)用不同派生層次中的show()函數(shù),只需在調(diào)用前給引用變量d賦以不同的值(使之指向不同的類對象)在基類中聲明同名函數(shù)時(shí),在最左面加一個(gè)關(guān)鍵字virtual,即: virtual 函數(shù)類型 函數(shù)名;-把函數(shù)聲明為虛函數(shù)虛函數(shù)的作用就是允許在派生類中重新定義與基類同名的函數(shù),并且可以通過基類指針或引用來訪問基類和派生類中的同名函數(shù)?!境绦?-9】在下面的程序中Student是基類,Graduate是派生類,它們都有display這個(gè)同名的函數(shù)。 #include

42、 #include using namespace std;class Student public: Student(int,string,float); /聲明構(gòu)造函數(shù) void display(); /聲明輸出函數(shù) protected: /受保護(hù)成員,派生類可以訪問 int num; string name; float score; ; Student:Student(int n,string nam,float s) num=n;name=nam;score=s; void Student:display() /定義輸出函數(shù) coutnum:numnname:namenscore:s

43、corenn; class Graduate:public Student public: Graduate(int,string,float,float); /聲明構(gòu)造函數(shù) void display(); /聲明輸出函數(shù) private: float pay; ; void Graduate:display() coutnum:numnname:namenscore:scorenpay=paydisplay(); pt=&grad1; pt-display(); return 0; 4.3 虛函數(shù)虛函數(shù)對程序作一點(diǎn)修改,在Student類中聲明display函數(shù)時(shí),在最左面加一個(gè)關(guān)鍵

44、字virtual。#include #include using namespace std;class Student public: Student(int,string,float); virtual void display(); protected: int num; string name; float score; ; 當(dāng)把基類的某個(gè)成員函數(shù)聲明為虛函數(shù)后,允許在其派生類中對該函數(shù)重新定義,賦予它新的功能,并且可以通過指向基類的指針指向同一類族中不同類的對象,從而調(diào)用其中的同名函數(shù)。 由虛函數(shù)實(shí)現(xiàn)的動態(tài)多態(tài)性就是:同一類族中不同類的對象,對同一函數(shù)調(diào)用作出不同的響應(yīng)。4.3 虛函

45、數(shù)虛函數(shù)虛函數(shù)的定義和使用方法是:在基類用virtual聲明成員函數(shù)為虛函數(shù)。這樣就可以在派生類中重新定義此函數(shù),為它賦予新的功能,并能方便地被調(diào)用。在類外定義虛函數(shù)時(shí),不必再加virtual。在派生類中重新定義此函數(shù),要求函數(shù)名、函數(shù)類型、函數(shù)參數(shù)個(gè)數(shù)和類型全部與基類的虛函數(shù)相同,并根據(jù)派生類的需要重新定義函數(shù)體。 C+規(guī)定,當(dāng)一個(gè)成員函數(shù)被聲明為虛函數(shù)后,其派生類中的同名函數(shù)都自動成為虛函數(shù)。因此在派生類重新聲明該虛函數(shù)時(shí),可以加virtual,也可以不加。 如果在派生類中沒有對基類的虛函數(shù)重新定義,則派生類簡單地繼承其直接基類的虛函數(shù)。定義一個(gè)指向基類對象的指針變量,并使它指向同一類族中

46、的某一對象。通過該指針變量調(diào)用此虛函數(shù),此時(shí)調(diào)用的就是指針變量指向的對象的同名函數(shù)。4.3 虛函數(shù)虛函數(shù)4.3.2 虛析構(gòu)函數(shù)虛析構(gòu)函數(shù)在C+語言中,不能聲明虛構(gòu)造函數(shù),但是可以聲明虛析構(gòu)函數(shù)。虛函數(shù)作為運(yùn)行過程中多態(tài)的基礎(chǔ),主要是針對對象的,而構(gòu)造函數(shù)是在對象產(chǎn)生之前運(yùn)行的,因此虛構(gòu)造函數(shù)是沒有意義的。析構(gòu)函數(shù)的作用是在對象撤銷之前做必要的“清理現(xiàn)場”的工作。當(dāng)派生類的對象從內(nèi)存中撤銷時(shí)一般先調(diào)用派生類的析構(gòu)函數(shù),然后再調(diào)用基類的析構(gòu)函數(shù)。如果用new運(yùn)算符建立了臨時(shí)對象,若基類中有析構(gòu)函數(shù),并且定義了一個(gè)指向該基類的指針變量。在程序用帶指針參數(shù)的delete運(yùn)算符撤銷對象時(shí),會發(fā)生一個(gè)情況

47、:系統(tǒng)會只執(zhí)行基類的析構(gòu)函數(shù),而不執(zhí)行派生類的析構(gòu)函數(shù)。將基類的析構(gòu)函數(shù)定義為虛析構(gòu)函數(shù),聲明語法為: virtual 類名();如果一個(gè)類的析構(gòu)函數(shù)是虛函數(shù),那么,由它派生而來的所有子類的析構(gòu)函數(shù)也是虛函數(shù)。 在使用指針引用時(shí)可以動態(tài)聯(lián)編,實(shí)現(xiàn)運(yùn)行時(shí)的多態(tài),保證使用基類類型的指針就能夠調(diào)用適當(dāng)?shù)奈鰳?gòu)函數(shù)針對不同的對象進(jìn)行清理工作。4.4 抽象類抽象類 抽象類是一種特殊的類,它為一族類提供統(tǒng)一的操作界面 抽象類是為了抽象和設(shè)計(jì)的目的而建立的,可以說,建立抽象類,就是為了通過它多態(tài)地使用其中的成員函數(shù)。 抽象類處于類層次的上層,一個(gè)抽象類無法聲明一個(gè)抽象類的對象,而只能通過繼承機(jī)制,生成抽象類的

48、非抽象派生類,然后再實(shí)例化。 抽象類-帶有純虛函數(shù)的類。4.4 抽象類抽象類4.4.1 純虛函數(shù)純虛函數(shù)純虛函數(shù)是一個(gè)在基類中說明的虛函數(shù),它在該基類中沒有定義具體的操作內(nèi)容,要求各派生類根據(jù)實(shí)際需要定義自己的版本,純虛函數(shù)的聲明格式為 virtual 函數(shù)類型函數(shù)名(參數(shù)名)= 0 ;它與一般虛函數(shù)成員的原型在書寫格式上的不同就在于后面加了“= 0”。聲明為純虛函數(shù)之后,基類中就不再給出函數(shù)的實(shí)現(xiàn)部分。純虛函數(shù)的函數(shù)體由派生類給出。在C+語言中,還有一種情況是函數(shù)體為空的虛函數(shù),請注意它和純虛函數(shù)的區(qū)別: 純虛函數(shù)根本就沒有函數(shù)體,而空的虛函數(shù)的函數(shù)體為空。 純虛函數(shù)所在的類是抽象類,不能直接進(jìn)行實(shí)例化; 空的虛函數(shù)所在的類是可以實(shí)例化的。 它們共同的特點(diǎn)是都可以派生出新的類,然后在新類中給出新的虛函數(shù)的實(shí)現(xiàn),而且這種新的實(shí)現(xiàn)可以具有多態(tài)特征。4.4抽象類抽象類4.4.2 抽象類抽象類帶有純虛函數(shù)的類是抽象類。抽象類派生出新

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論