C語言試題、學習、考試大全學習教案_第1頁
C語言試題、學習、考試大全學習教案_第2頁
C語言試題、學習、考試大全學習教案_第3頁
C語言試題、學習、考試大全學習教案_第4頁
C語言試題、學習、考試大全學習教案_第5頁
已閱讀5頁,還剩52頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、會計學1C語言試題語言試題(sht)、學習、考試大全、學習、考試大全第一頁,共57頁。13.1 函數(shù)重載函數(shù)重載 13.2 運算符重載運算符重載 13.3 靜態(tài)靜態(tài)(jngti)聯(lián)編聯(lián)編 13.4 動態(tài)聯(lián)編和虛函數(shù)動態(tài)聯(lián)編和虛函數(shù) 13.5 純虛函數(shù)和抽象類純虛函數(shù)和抽象類 第1頁/共57頁第二頁,共57頁。第第 13 章章 多態(tài)性多態(tài)性 多態(tài)性是實現(xiàn)多態(tài)性是實現(xiàn)(shxin) OOP 的關鍵技術之一。的關鍵技術之一。 在在C+中,多態(tài)性分為兩種:中,多態(tài)性分為兩種: 靜態(tài)靜態(tài)(jngti)多態(tài)多態(tài) 動態(tài)多態(tài)動態(tài)多態(tài) 函數(shù)重載和運算符重載屬于靜態(tài)多態(tài)。函數(shù)重載和運算符重載屬于靜態(tài)多態(tài)。函數(shù)重載

2、:相同函數(shù)名可以函數(shù)重載:相同函數(shù)名可以(ky)完成不同功能。完成不同功能。運算符重載:相同運算符完成不同功能。運算符重載:相同運算符完成不同功能。 動態(tài)多態(tài)動態(tài)多態(tài)是指:程序執(zhí)行過程中確定的關系,是指:程序執(zhí)行過程中確定的關系, 如動態(tài)確定函數(shù)的調(diào)用關系。如動態(tài)確定函數(shù)的調(diào)用關系。 運行時的多態(tài)(動態(tài)多態(tài))運行時的多態(tài)(動態(tài)多態(tài)) 是通過類的繼承和虛函數(shù)來實現(xiàn)的。是通過類的繼承和虛函數(shù)來實現(xiàn)的。第2頁/共57頁第三頁,共57頁。13.1 函數(shù)函數(shù)(hnsh)重載重載 參見參見5.6節(jié)(略)節(jié)(略) 13.2 重載重載(zhn zi)運算符運算符 C+中所有的運算符都已預先中所有的運算符都已預

3、先(yxin)定義了用法及意義。定義了用法及意義。 如:如:+ * / = 等,適用于已有的數(shù)據(jù)類型。等,適用于已有的數(shù)據(jù)類型。 已定義的已定義的用法及意義是不允許用戶改變的。用法及意義是不允許用戶改變的。 如果用戶定義了新的數(shù)據(jù)類型,希望已定義的運算符如果用戶定義了新的數(shù)據(jù)類型,希望已定義的運算符 能適應新的數(shù)據(jù)類型,能適應新的數(shù)據(jù)類型, 如如: 前述前述 Complex 類的加法運算類的加法運算Complex c1, c2, c3;c3 = add(c1, c2); /以前通過函數(shù)實現(xiàn)加法運算以前通過函數(shù)實現(xiàn)加法運算c2.add(c3); / 或或通過成員函數(shù)實現(xiàn)通過成員函數(shù)實現(xiàn)c3 =

4、c1 + c2; /能否直觀地寫成這樣?能否直觀地寫成這樣?能能 ! 運算符的重載可以達到此目的。運算符的重載可以達到此目的。第3頁/共57頁第四頁,共57頁。 允許允許(ynx)重載重載 和和 不允許不允許(ynx)重載的運算符見重載的運算符見13-1和和13-2表。表。13.2.1 運算符重載運算符重載(zhn zi)的幾點說的幾點說明明重載運算符的限制重載運算符的限制(1)只能)只能(zh nn)對已有運算符重載,不可臆造新的運算符。對已有運算符重載,不可臆造新的運算符。(2)不允許改變運算符的優(yōu)先級和結合性。)不允許改變運算符的優(yōu)先級和結合性。(3)不允許改變運算符的語法結構,)不允許

5、改變運算符的語法結構, 如二元運算符只能如二元運算符只能(zh nn)重載成二元運算符,重載成二元運算符, 一元運算符只能一元運算符只能(zh nn)重載成一元運算符。重載成一元運算符。第4頁/共57頁第五頁,共57頁。1.重載為類的成員重載為類的成員(chngyun)函數(shù)函數(shù) 在類內(nèi)定義在類內(nèi)定義(dngy)運算符重載函數(shù)的格式為:運算符重載函數(shù)的格式為: operator ( ) 以以 operator 為關鍵字,編譯器可以很容易將為關鍵字,編譯器可以很容易將運算符重載函數(shù)與其他成員運算符重載函數(shù)與其他成員(chngyun)函數(shù)區(qū)別開來。函數(shù)區(qū)別開來。例例13.2 實現(xiàn)復數(shù)類的實現(xiàn)復數(shù)類的

6、“+”,“-”等重載運算等重載運算 關鍵部分見下頁關鍵部分見下頁13.2.2 運算符重載的兩種方式運算符重載的兩種方式在類外定義運算符重載函數(shù)的格式為:在類外定義運算符重載函數(shù)的格式為: :operator ( )特殊的成員函數(shù)名特殊的成員函數(shù)名第5頁/共57頁第六頁,共57頁。class Complex float Real, Image;public: . Complex operator +(const Complex &c); Complex operator +(double); Complex operator-(const Complex &c); Complex

7、 operator-(double); Complex operator-(void); . ;Complex Complex:operator +(const Complex &c) return Complex (Real+c.Real, Image+c.Image); Complex Complex:operator +(double r) return Complex(Real+r, Image); Complex Complex:operator-(void) return Complex(-Real, -Image); 第6頁/共57頁第七頁,共57頁。void main(

8、 ) Complex c1(2, 3), c2(4, -2), c3; c3 = c1+c2 ; c3 = c1+5 ; c3 = - c1; 編譯器將編譯器將 c1+c2 解釋解釋(jish)為:為:c1.operator+(c2)將將 c1+5 解釋解釋(jish)為:為:c1.operator+(5)第第1個運算量是對象個運算量是對象(duxing),第,第2個運算量是參數(shù)。個運算量是參數(shù)。閱讀教材上程序全文閱讀教材上程序全文(講解略)(講解略)將將 - c1 解釋為:解釋為:c1.operator( ) 當用成員函數(shù)實現(xiàn)運算符的重載時,重載函數(shù)的當用成員函數(shù)實現(xiàn)運算符的重載時,重載函數(shù)

9、的 參數(shù)個數(shù)只能是參數(shù)個數(shù)只能是 0 個或個或 1 個。分別實現(xiàn):一元、二元個。分別實現(xiàn):一元、二元 運算符的重載。運算符的重載。第7頁/共57頁第八頁,共57頁。2.重載重載(zhn zi)為友元函數(shù)為友元函數(shù) 例例13.3 用友元函數(shù)實現(xiàn)用友元函數(shù)實現(xiàn)(shxin)復數(shù)類的復數(shù)類的“+”和和“” 重載運算重載運算 關鍵部分見下頁關鍵部分見下頁在在類內(nèi)類內(nèi)定義友元重載函數(shù)的格式為:定義友元重載函數(shù)的格式為:friend operator ( )在在類外類外定義友元重載函數(shù)的格式為:定義友元重載函數(shù)的格式為: operator ( )第8頁/共57頁第九頁,共57頁。class Complex

10、 float Real, Image;public: . friend Complex operator +(const Complex &c1, const Complex &c2); friend Complex operator(const Complex &c); . ;Complex operator +(const Complex &c1, const Complex &c2)/二元運算二元運算(yn sun) Complex t; t.Real=c1.Real+c2.Real; t.Image=c1.Image+c2.Image; retu

11、rn t;Complex operator(const Complex c) /一元運算一元運算(yn sun) return Complex(c.Real, c.Image) ;不是類的成員函數(shù)不是類的成員函數(shù)在在 main( )函數(shù)函數(shù)(hnsh)中中,若有若有 Complex c1,c2; 則編譯器將則編譯器將 c1+c2 解釋為:解釋為:operator+(c1, c2)將將 c1 解釋解釋(jish)為:為:operator(c1)第9頁/共57頁第十頁,共57頁。閱讀教材閱讀教材(jioci)上程序全文(講解略)上程序全文(講解略) 當用友元函數(shù)實現(xiàn)當用友元函數(shù)實現(xiàn)(shxin)運

12、算符的重載時,重載函數(shù)的運算符的重載時,重載函數(shù)的 參數(shù)個數(shù)只能是參數(shù)個數(shù)只能是1 個或個或 2 個。個。 分別實現(xiàn)分別實現(xiàn)(shxin):一元運算符重載、二元運算符重載:一元運算符重載、二元運算符重載3.兩種重載方式兩種重載方式(fngsh)的比較的比較 成員實現(xiàn):成員實現(xiàn):將將 c1+c2 解釋為:解釋為:c1.operator +(c2)友元實現(xiàn):友元實現(xiàn):將將 c1+c2 解釋為:解釋為:operator +(c1, c2)成員實現(xiàn):成員實現(xiàn):將將 c1+5.6 解釋為:解釋為:c1.operator +(5.6)友元實現(xiàn):友元實現(xiàn):將將 c1+5.6 解釋為:解釋為:operator

13、 +(c1, 5.6)成員實現(xiàn):成員實現(xiàn):將將 5.6 + c1解釋為:解釋為: 5.6.operator + (c1) 友元實現(xiàn):友元實現(xiàn):將將 5.6 + c1解釋為:解釋為:operator + ( 5.6, c1)第10頁/共57頁第十一頁,共57頁。因此因此(ync):對一般的二元運算符重載為友元函數(shù)比重載為成員函數(shù)對一般的二元運算符重載為友元函數(shù)比重載為成員函數(shù)更優(yōu)越。更優(yōu)越。但是對于賦值運算符,將其重載為成員函數(shù)較好,因為但是對于賦值運算符,將其重載為成員函數(shù)較好,因為賦值運算符是一個二元運算符,賦值運算符是一個二元運算符,其語法格式為其語法格式為 =,第一個運算量必須是對象(變

14、量也是對象),通過對象第一個運算量必須是對象(變量也是對象),通過對象調(diào)用成員函數(shù)比較自然。調(diào)用成員函數(shù)比較自然。若重載為友元,則可能會出現(xiàn)若重載為友元,則可能會出現(xiàn)5.6=c這樣的表達式,與這樣的表達式,與賦值表達式的語義不一致。賦值表達式的語義不一致。 第11頁/共57頁第十二頁,共57頁。定義友元的目的是在友元函數(shù)中直接訪問類的私有成員,定義友元的目的是在友元函數(shù)中直接訪問類的私有成員,實際上,也可以通過公有函數(shù)接口訪問類的私有成員,實際上,也可以通過公有函數(shù)接口訪問類的私有成員,所以實現(xiàn)所以實現(xiàn)(shxin)運算符重載,可以即不用成員函數(shù),運算符重載,可以即不用成員函數(shù),也不用友元函數(shù)

15、。也不用友元函數(shù)。class Complex float Real, Image;public: Complex(double r=0, double i=0) Real=r; Image=i; void SetReal(double Real) Complex:Real = Real; void SetImage(double Image) Complex:Image = Image; double GetReal( ) return(Real); double GetImage( ) return(Image); ; 4.使用使用(shyng)非成員、非友元實現(xiàn)運算符的重載非成員、非友元實

16、現(xiàn)運算符的重載例例13.4:第12頁/共57頁第十三頁,共57頁。Complex operator +(Complex &c1, Complex &c2) /二元運算二元運算(yn sun) Complex t; t.SetReal( c1.GetReal( )+c2.GetReal( ) ); t.SetImage( c1.GetImage( )+c2.GetImage( ) ); return t; void main( )Complex c1(2, 3), c2(4, 8), c3;c3 = c1+c2;c3.Show( );編譯器將編譯器將 c1+c2 解釋解釋(jis

17、h)為:為:operator +(c1, c2)第13頁/共57頁第十四頁,共57頁。對于對于(duy)Complex類,如有類,如有Complex c1(2, 3), c2; 則自動將則自動將 c2=c1; 處理成:處理成: c2.Real = c1.Real; c2.Image = c1. Image; 一般不會出現(xiàn)問題。一般不會出現(xiàn)問題。 5. 何時必須何時必須(bx)重載重載 = 和和 += 運算符?運算符? 相同類型的對象之間是可以直接賦值的,相同類型的對象之間是可以直接賦值的,C+將賦值將賦值處理成兩個對象的各個處理成兩個對象的各個(gg)成員直接賦值。兩個對成員直接賦值。兩個對象

18、的對應數(shù)據(jù)成員逐一賦值。象的對應數(shù)據(jù)成員逐一賦值。例例13.5 在類中,用字符數(shù)組實現(xiàn)字符串。在類中,用字符數(shù)組實現(xiàn)字符串。 見見 “第第13章章 多態(tài)性多態(tài)性(例子例子).doc”第14頁/共57頁第十五頁,共57頁。Num數(shù)組數(shù)組Name數(shù)組數(shù)組Score整數(shù)整數(shù)stud1存儲空間存儲空間Num數(shù)組數(shù)組Name數(shù)組數(shù)組Score整數(shù)整數(shù)stud2存儲空間存儲空間程序程序(chngx)中中A行使用賦值運算符進行對象整體賦值,行使用賦值運算符進行對象整體賦值, C+將其處理成各個成員逐一賦值將其處理成各個成員逐一賦值,如下圖所示:如下圖所示: :C+默認默認(mrn)的處理是:的處理是:str

19、cpy(stud2.Num, stud1.Num); strcpy(stud2.Name, stud1.Name); stud2.Score = stud1.Score; 。 但是如果對象的成員中有成員指向但是如果對象的成員中有成員指向(zh xin)動態(tài)分配的動態(tài)分配的 數(shù)據(jù)空間就會出現(xiàn)問題。數(shù)據(jù)空間就會出現(xiàn)問題。 第15頁/共57頁第十六頁,共57頁。例例13.6 在類中,用指針實現(xiàn)字符串,在類中,用指針實現(xiàn)字符串, 即字符串的空間是動態(tài)分配的。即字符串的空間是動態(tài)分配的。 class Studentchar *Nump; /學號,注意學號,注意(zh y):用指針實現(xiàn):用指針實現(xiàn)char

20、 *Namep; /姓名,注意姓名,注意(zh y):用指針實現(xiàn):用指針實現(xiàn)int Score; /成績成績public: Student(char *nump=NULL, char *namep=NULL, int score=0) if(nump) /構造函數(shù)構造函數(shù) Nump = new charstrlen(nump)+1;strcpy(Nump, nump); /動態(tài)分配存儲空間動態(tài)分配存儲空間 else Nump=NULL; if(namep) Score=score;第16頁/共57頁第十七頁,共57頁。Student( ) / 析構函數(shù),釋放指針析構函數(shù),釋放指針(zhzhn)

21、指向的空間指向的空間 if(Nump)delete Nump;if(Namep)delete Namep;void Show( ) if(Nump & Namep) coutNum=NumptName=NameptScore=Scoreendl;第17頁/共57頁第十八頁,共57頁。void main( )Student stud1(01201, Mary, 88), stud2;stud2=stud1; /Astud1.Show( );stud2.Show( );cout.flush( ); /BNump指針指針Namep指針指針Score整數(shù)整數(shù)stud2存儲空間存儲空間Nump指

22、針指針Namep指針指針Score整數(shù)整數(shù)stud1存儲空間存儲空間01201Mary首先撤消對象首先撤消對象stud2,然后撤消對象,然后撤消對象stud1 ,出問題,出問題(wnt)!同一對象被撤銷兩次。同一對象被撤銷兩次。 編譯器將編譯器將A行處理行處理(chl)成:成:第18頁/共57頁第十九頁,共57頁。解決辦法,在類中增加賦值解決辦法,在類中增加賦值 = 重載重載(zhn zi)函數(shù):函數(shù):Student & operator=(const Student &stud) / 返回值為對象自身的引用返回值為對象自身的引用(ynyng) if(Nump)delete N

23、ump; / C 釋放對象自身的原串空間釋放對象自身的原串空間 if(Namep)delete Namep; / D 釋放對象自身的原串空間釋放對象自身的原串空間 if(stud.Nump) / 根據(jù)賦值對象的空間大小給被賦值對象分配空間根據(jù)賦值對象的空間大小給被賦值對象分配空間 Nump = new charstrlen(stud.Nump)+1;strcpy(Nump, stud.Nump); else Nump=NULL; if(stud.Namep) / 根據(jù)賦值對象的空間大小給被賦值對象分配空間根據(jù)賦值對象的空間大小給被賦值對象分配空間 Namep = new charstrlen(

24、stud.Namep)+1;strcpy(Namep, stud.Namep); else Namep=NULL; Score=stud.Score; return *this; / *this是對象自身是對象自身 第19頁/共57頁第二十頁,共57頁。Nump指針指針Namep指針指針Score整數(shù)整數(shù)stud2存儲空間存儲空間Nump指針指針Namep指針指針Score整數(shù)整數(shù)stud1存儲空間存儲空間01201Mary01201Mary在賦值時,為目的對象在賦值時,為目的對象(duxing)的指針重新分配指向的字的指針重新分配指向的字符串空間。符串空間。增加賦值增加賦值 = 重載函數(shù)后,

25、對象重載函數(shù)后,對象(duxing)賦值后的存儲空賦值后的存儲空間如下:間如下:這樣,程序結束這樣,程序結束(jish)時,分別撤銷兩個對象,程序正時,分別撤銷兩個對象,程序正確運行!確運行!第20頁/共57頁第二十一頁,共57頁。6對于對于+=(或(或=)運算符,重載函數(shù))運算符,重載函數(shù)(hnsh)的返回值為的返回值為void類型或本類類型對象的區(qū)別類型或本類類型對象的區(qū)別 例例13.7 見見 “第第13章章 多態(tài)性多態(tài)性(例子例子(l zi).doc”若重載若重載(zhn zi)為返回為返回void類型,則本類對象不類型,則本類對象不可連續(xù)賦值??蛇B續(xù)賦值。若重載若重載(zhn zi)為

26、返回本類類型,則本類對象可為返回本類類型,則本類對象可以連續(xù)賦值。以連續(xù)賦值。第21頁/共57頁第二十二頁,共57頁。7對于對于+=(或(或=)運算符,返回本類對象與返回本類)運算符,返回本類對象與返回本類對象的引用對象的引用(ynyng)的區(qū)別的區(qū)別 比較比較(bjio)下面兩例,先看第一個例子:下面兩例,先看第一個例子: Complex Complex :operator+=(const Complex &c) Real+=c.Real; Image+=c.Image; return *this; 此函數(shù)的返回值為本類對象,此函數(shù)的返回值為本類對象,C+的處理是:用返回的對的處理是

27、:用返回的對象值象值*this初始化內(nèi)存臨時對象(調(diào)用拷貝構造函數(shù)),初始化內(nèi)存臨時對象(調(diào)用拷貝構造函數(shù)),從本函數(shù)返回后,用內(nèi)存臨時對象作為調(diào)用函數(shù)的結果從本函數(shù)返回后,用內(nèi)存臨時對象作為調(diào)用函數(shù)的結果。 第22頁/共57頁第二十三頁,共57頁。再看第二個例子:再看第二個例子:Complex Complex :operator+=(const Complex &c) Real+=c.Real; Image+=c.Image; Complex temp = *this ;return temp;C+的處理是:調(diào)用拷貝構造函數(shù),用返回的對象值的處理是:調(diào)用拷貝構造函數(shù),用返回的對象值t

28、emp初始化內(nèi)存臨時初始化內(nèi)存臨時(ln sh)對象,內(nèi)存臨時對象,內(nèi)存臨時(ln sh)對對象作為調(diào)用函數(shù)的結果。象作為調(diào)用函數(shù)的結果。 第23頁/共57頁第二十四頁,共57頁。從上面兩個小例子可以看出,若重載函數(shù)返回對象值,從上面兩個小例子可以看出,若重載函數(shù)返回對象值,則返回則返回*this和返回和返回temp均可。均可。但要注意,因為返回對象值時需要調(diào)用但要注意,因為返回對象值時需要調(diào)用(dioyng)拷貝拷貝構造函數(shù)初始化內(nèi)存臨時對象,因此若對象有動態(tài)分配構造函數(shù)初始化內(nèi)存臨時對象,因此若對象有動態(tài)分配的存儲空間,就必須定義拷貝構造函數(shù)。的存儲空間,就必須定義拷貝構造函數(shù)。 第24頁

29、/共57頁第二十五頁,共57頁。第三個例子第三個例子(l zi): Complex & Complex :operator+=(const Complex &c) Real+=c.Real; Image+=c.Image;return *this; 本例的返回值為本類對象的引用,不需初始化內(nèi)存臨時對象本例的返回值為本類對象的引用,不需初始化內(nèi)存臨時對象,返回值是對象自身,即,返回值是對象自身,即*this。因為不需要初始化內(nèi)存臨。因為不需要初始化內(nèi)存臨時對象,效率較高,所以像時對象,效率較高,所以像 +=、= 等改變對象值的重載函等改變對象值的重載函數(shù)最好返回對象的引用。數(shù)最好

30、返回對象的引用。 第25頁/共57頁第二十六頁,共57頁。第四個例子:第四個例子:Complex & Complex :operator+=(const Complex &c) Real+=c.Real; Image += c.Image; Complex temp = *this ;return temp;此時,出現(xiàn)問題。因為返回的是對象的引用(即對象自此時,出現(xiàn)問題。因為返回的是對象的引用(即對象自身,不借助于內(nèi)存臨時對象),系統(tǒng)要求在執(zhí)行流程身,不借助于內(nèi)存臨時對象),系統(tǒng)要求在執(zhí)行流程(lichng)返回到調(diào)用處時,返回值是存在的。但是本例返回到調(diào)用處時,返回值是存在的

31、。但是本例返回值是函數(shù)內(nèi)部的局部對象返回值是函數(shù)內(nèi)部的局部對象temp,而局部對象在函數(shù),而局部對象在函數(shù)返回前,其空間是被撤消的。返回前,其空間是被撤消的。第26頁/共57頁第二十七頁,共57頁。結論:結論: 返回本類對象時,可以用對象自身和局部對象做為返回值返回本類對象時,可以用對象自身和局部對象做為返回值(有時需要定義拷貝(有時需要定義拷貝(kobi)構造函數(shù))。構造函數(shù))。 返回對象的引用時,不能用局部對象做為返回值。返回對象的引用時,不能用局部對象做為返回值。例例13.8對于字符串類,重載對于字符串類,重載 = 運算符,返回對象自身的引運算符,返回對象自身的引用。就本例而言,可以用。

32、就本例而言,可以(ky)不定義拷貝構造函數(shù),程序能不定義拷貝構造函數(shù),程序能正確運行。正確運行。 見見 “第第13章章 多態(tài)性多態(tài)性(例子例子).doc”第27頁/共57頁第二十八頁,共57頁。8.調(diào)用拷貝調(diào)用拷貝(kobi)構造函數(shù)構造函數(shù) 和和 調(diào)用賦值運算符重載函數(shù)的時機調(diào)用賦值運算符重載函數(shù)的時機 class Complexdouble Real, Image;public:Complex(double r=0, double i=0) / 構造函數(shù)構造函數(shù) Real=r; Image=i; Complex(Complex &c) / 拷貝拷貝(kobi)構造函數(shù)構造函數(shù) Re

33、al=c.Real; Image=c.Image; coutCall copy Real Imagen; ;void main( )Complex c1(2, 3), c2(4, -2);Complex c3=c1; c1=c2; 程序程序(chngx)的運行結果是?的運行結果是?調(diào)用了拷貝構造函數(shù)調(diào)用了拷貝構造函數(shù)未調(diào)用拷貝構造函數(shù)未調(diào)用拷貝構造函數(shù)Call copy 2 3v只有在產(chǎn)生新對象時,調(diào)用構造函數(shù)。只有在產(chǎn)生新對象時,調(diào)用構造函數(shù)。v用已有對象初始化新產(chǎn)生的對象時,用已有對象初始化新產(chǎn)生的對象時, 調(diào)用拷貝構造函數(shù)。調(diào)用拷貝構造函數(shù)。v賦值運算賦值運算 = , 不調(diào)用拷貝構造函數(shù)

34、。不調(diào)用拷貝構造函數(shù)。第28頁/共57頁第二十九頁,共57頁。13.2.3 類型轉(zhuǎn)換函數(shù)將本類對象類型轉(zhuǎn)換函數(shù)將本類對象(duxing)轉(zhuǎn)換成其轉(zhuǎn)換成其他類對象他類對象(duxing)例例: Complex c(3, 2); double x=6.2;如果有如果有: c=x; /類型不一致類型不一致(yzh) 或或: x=c; /類型不一致類型不一致(yzh)則系統(tǒng)自動處理為則系統(tǒng)自動處理為: c = Complex(x); /需作類型轉(zhuǎn)換需作類型轉(zhuǎn)換 x = double(c); /需作類型轉(zhuǎn)換需作類型轉(zhuǎn)換對于,通過以前所學的對于,通過以前所學的構造函數(shù)構造函數(shù)實現(xiàn)類型轉(zhuǎn)換,實現(xiàn)類型轉(zhuǎn)換,

35、將其他類型的數(shù)據(jù)轉(zhuǎn)換成本類數(shù)據(jù)將其他類型的數(shù)據(jù)轉(zhuǎn)換成本類數(shù)據(jù)。對于,使用本節(jié)將介紹的類型轉(zhuǎn)換對于,使用本節(jié)將介紹的類型轉(zhuǎn)換運算符重載函數(shù)運算符重載函數(shù), 將本類數(shù)據(jù)轉(zhuǎn)換成將本類數(shù)據(jù)轉(zhuǎn)換成其他類型的數(shù)據(jù)。其他類型的數(shù)據(jù)。構造函數(shù):構造函數(shù):Complex:Complex(double r) real = r ; image = 0; 第29頁/共57頁第三十頁,共57頁。定義定義(dngy)類型轉(zhuǎn)換函數(shù)類型轉(zhuǎn)換函數(shù): 功能:將功能:將 類對象自動類對象自動(zdng)轉(zhuǎn)換成轉(zhuǎn)換成 類型對象類型對象類型轉(zhuǎn)換函數(shù)類型轉(zhuǎn)換函數(shù)(hnsh)只能用成員函數(shù)只能用成員函數(shù)(hnsh)實現(xiàn)實現(xiàn), 不能用友元函

36、數(shù)不能用友元函數(shù)(hnsh)實現(xiàn)。實現(xiàn)。在類內(nèi)定義類型轉(zhuǎn)換函數(shù)的一般格式為:在類內(nèi)定義類型轉(zhuǎn)換函數(shù)的一般格式為:operator ( ) . 在類外定義類型轉(zhuǎn)換函數(shù)的一般格式為:在類外定義類型轉(zhuǎn)換函數(shù)的一般格式為: : operator ( ) . 該函數(shù)不能有參數(shù),該函數(shù)不能有參數(shù),不能寫返回值類型,不能寫返回值類型, 因返回值類型已確定。因返回值類型已確定。第30頁/共57頁第三十一頁,共57頁。例例13.10 類型轉(zhuǎn)換函數(shù)類型轉(zhuǎn)換函數(shù)(hnsh)的定義和使用的定義和使用 #include class Complexdouble Real, Image;public:Complex(dou

37、ble r=0, double i=0) Real=r; Image=i; operator double ( ) / A 類型轉(zhuǎn)換函數(shù)類型轉(zhuǎn)換函數(shù)(hnsh), / 將將 Complex 類轉(zhuǎn)換成類轉(zhuǎn)換成 double 類類 return Real; ;void main( ) Complex c(3,2);double x;x = c; / B cout x= x endl;/ 即即 x = double (c) ;系統(tǒng)自動處理為系統(tǒng)自動處理為 x = c.operator double( );第31頁/共57頁第三十二頁,共57頁。例例13.11 成員函數(shù)成員函數(shù)(hnsh)和類型轉(zhuǎn)換函

38、數(shù)和類型轉(zhuǎn)換函數(shù)(hnsh)的比較的比較見見 “第第13章章 多態(tài)性多態(tài)性(例子例子).doc”其中其中(qzhng)主函數(shù)為:主函數(shù)為:void main(void)RMB r(23, 8, 6);int r1, r2, r3;r1= r ; /處理成處理成 r1 = r.operator int( );r2= int(r); /處理成處理成 r2 = r.operator int( ) ;r3= r.GetFen( ); coutr1=r1endl;coutr2=r2endl;coutr3=r3endl; 使用使用類型自動轉(zhuǎn)換類型自動轉(zhuǎn)換 較方便、自然。較方便、自然。第32頁/共57頁第三

39、十三頁,共57頁。13.2.4 其他其他(qt)運算符的重載運算符的重載1重載重載+、-運算符運算符 重載重載(zhn zi)前置前置 + 運算符的成員函數(shù)的一般格式為:運算符的成員函數(shù)的一般格式為: :operator+ ( ) . 重載重載后置后置 + 運算符的運算符的成員成員函數(shù)的一般格式為:函數(shù)的一般格式為: :operator+ (int) . int 用于區(qū)分,沒有實際意義,用于區(qū)分,沒有實際意義,可給出實參,也可以不給出實參??山o出實參,也可以不給出實參。第33頁/共57頁第三十四頁,共57頁。重載前置重載前置(qin zh) + 運算符的友元函數(shù)的一般格式為:運算符的友元函數(shù)的

40、一般格式為:friend operator+ ( &obj ) . 重載后置重載后置+運算符的友元函數(shù)運算符的友元函數(shù)(hnsh)的一般格式為:的一般格式為:friend operator+ ( &obj, int) . int 用于區(qū)分,沒有實際意義,用于區(qū)分,沒有實際意義,可給出實參,也可以不給出實參??山o出實參,也可以不給出實參。例例13.12 實現(xiàn)實現(xiàn)+和和 - 的前置和后置運算符重載,的前置和后置運算符重載, 程序見程序見 “第第13章章 多態(tài)性多態(tài)性(例子例子).doc”第34頁/共57頁第三十五頁,共57頁。13.2.5 字符串類字符串類C+ 提供的字符串處理能力

41、提供的字符串處理能力(nngl)較弱,如不能用運較弱,如不能用運算符直接對字符串對象進行加、減等操作,算符直接對字符串對象進行加、減等操作,而必須通過字符串處理函數(shù)來實現(xiàn)拷貝、連接等操作。而必須通過字符串處理函數(shù)來實現(xiàn)拷貝、連接等操作。如:如:char s110=abc, s210=123; strcpy(s1, s2); /不能寫成不能寫成 s1= s2; strcat(s1, s2); /不能寫成不能寫成 s1= s1+s2;能否定義一個字符串類:能否定義一個字符串類:String 實現(xiàn):實現(xiàn): String s1(abc), s2(123), s3; s1 = s2; s3 = s1 +

42、 s2;能能! 可以利用可以利用C+提供的運算符重載實現(xiàn)。提供的運算符重載實現(xiàn)。第35頁/共57頁第三十六頁,共57頁。例例13.18 定義字符串類定義字符串類String,并測試重載的運算,并測試重載的運算符以及成員符以及成員(chngyun)函數(shù)函數(shù) 程序見程序見 “第第13章章 多態(tài)性多態(tài)性(例子例子).doc”,或閱讀教材,或閱讀教材上的程序。上的程序。重點講解重點講解(jingji):(1) 說明:函數(shù)名后的說明:函數(shù)名后的 const(2) (拷貝拷貝)構造函數(shù),在主函數(shù)中如何使用?構造函數(shù),在主函數(shù)中如何使用?(3) 重載賦值重載賦值 = 運算符運算符(4) 重載重載 + 運算符

43、運算符(5) 類型轉(zhuǎn)換函數(shù)類型轉(zhuǎn)換函數(shù) operator const char *(6) 刪除子串圖示見下頁刪除子串圖示見下頁第36頁/共57頁第三十七頁,共57頁。刪除刪除(shnch)子串:子串:String operator - (const String &s1, const char *s2 ) lenp1p2s1.Strps2t.Strp第37頁/共57頁第三十八頁,共57頁。13.3 靜態(tài)靜態(tài)(jngti)聯(lián)編聯(lián)編聯(lián)編是指一個計算機程序彼此關聯(lián)聯(lián)編是指一個計算機程序彼此關聯(lián)(gunlin)的過程。的過程。 在本章在本章(bn zhn)中指函數(shù)間調(diào)用關系的確定。中指函數(shù)間調(diào)

44、用關系的確定。按照聯(lián)編所確定的時刻不同,可分為兩種:按照聯(lián)編所確定的時刻不同,可分為兩種: 靜態(tài)聯(lián)編靜態(tài)聯(lián)編和和動態(tài)聯(lián)編動態(tài)聯(lián)編。 靜態(tài)聯(lián)編是指聯(lián)編出現(xiàn)在編譯連接階段,靜態(tài)聯(lián)編是指聯(lián)編出現(xiàn)在編譯連接階段, 即函數(shù)調(diào)用關系的確定是在程序執(zhí)行之前。即函數(shù)調(diào)用關系的確定是在程序執(zhí)行之前。這種聯(lián)編又稱早期聯(lián)編,這種聯(lián)編又稱早期聯(lián)編, 通過這種聯(lián)編可實現(xiàn)靜態(tài)多態(tài)。通過這種聯(lián)編可實現(xiàn)靜態(tài)多態(tài)。 第38頁/共57頁第三十九頁,共57頁。例例13.20 普通函數(shù)的靜態(tài)聯(lián)編普通函數(shù)的靜態(tài)聯(lián)編#include int add(int a, int b) /重載函數(shù)重載函數(shù)1 return(a+b); double

45、 add(double a, double b) /重載函數(shù)重載函數(shù)2 return(a+b); void main( ) coutadd(1, 2)t; /編譯時確定調(diào)用重載函數(shù)編譯時確定調(diào)用重載函數(shù)1 coutadd(1.1, 2.2)n; /編譯時確定調(diào)用重載函數(shù)編譯時確定調(diào)用重載函數(shù)2在編譯連接階段,就能根據(jù)在編譯連接階段,就能根據(jù)(gnj)參數(shù)的個數(shù)和類型確定參數(shù)的個數(shù)和類型確定調(diào)用的是哪一個函數(shù)。調(diào)用的是哪一個函數(shù)。 第39頁/共57頁第四十頁,共57頁。例例13.21 讀書讀書(d sh)上程序上程序 重點講解重點講解(jingji):double CalcArea( Point

46、 &p ) return(p.Area( ); /A 編譯連接時確定調(diào)用函數(shù)編譯連接時確定調(diào)用函數(shù) 1void main( ) Rectangle r(0, 0, 1, 1); Circle c(0, 0, 1); coutCalcArea( r )t; coutCalcArea( c )n;Point Rectangle Circle能否找到一種機制,能否找到一種機制,讓讓CalcArea( )函數(shù)變成一個函數(shù)變成一個通用的求面積通用的求面積(min j)的函數(shù)。的函數(shù)。這就是這就是C+提供的動態(tài)聯(lián)編和提供的動態(tài)聯(lián)編和虛函數(shù)應完成的工作。虛函數(shù)應完成的工作。 用派生類實參初始化基類型

47、參,用派生類實參初始化基類型參,p只能引用基類的成員。只能引用基類的成員。第40頁/共57頁第四十一頁,共57頁。13.4 動態(tài)動態(tài)(dngti)聯(lián)編和虛函數(shù)聯(lián)編和虛函數(shù)運行階段才能運行階段才能(cinng)確定函數(shù)的調(diào)用關系,這就是動態(tài)聯(lián)編確定函數(shù)的調(diào)用關系,這就是動態(tài)聯(lián)編 動態(tài)聯(lián)編又稱滯后動態(tài)聯(lián)編又稱滯后(zh hu)聯(lián)編、晚期聯(lián)編,聯(lián)編、晚期聯(lián)編, 動態(tài)聯(lián)編技術能實現(xiàn)動態(tài)多態(tài)。動態(tài)聯(lián)編技術能實現(xiàn)動態(tài)多態(tài)。 必須將類的成員函數(shù)定義成虛函數(shù),必須將類的成員函數(shù)定義成虛函數(shù), 才可以實現(xiàn)動態(tài)聯(lián)編。才可以實現(xiàn)動態(tài)聯(lián)編。 將成員函數(shù)定義成虛函數(shù)的格式為:將成員函數(shù)定義成虛函數(shù)的格式為:virtua

48、l ( ) 13.4.1 虛函數(shù)虛函數(shù)第41頁/共57頁第四十二頁,共57頁。重點重點(zhngdin)講解:講解:double CalcArea(Point &p) return( p.Area( ) ); /A Area( )是虛函數(shù)是虛函數(shù)void main( ) Point p(1, 2); Rectangle r(0, 0, 1, 1); Circle c(0, 0, 1); coutCalcArea( p )t CalcArea( r )t CalcArea( c )n;例例13.22 閱讀閱讀(yud)書上程序書上程序Area( )是虛函數(shù)是虛函數(shù) ,C+ 規(guī)定規(guī)定(gu

49、dng),在在 A 行保留相關的行保留相關的三個虛函數(shù)入口地址三個虛函數(shù)入口地址 。在程序的運行階段,在程序的運行階段,根據(jù)實參的類型來確定根據(jù)實參的類型來確定調(diào)用哪一個虛函數(shù)。調(diào)用哪一個虛函數(shù)。通用的通用的求求面積函數(shù)面積函數(shù)第42頁/共57頁第四十三頁,共57頁。(1)派生類的虛函數(shù)必須)派生類的虛函數(shù)必須(bx)與基類虛函數(shù)同名,與基類虛函數(shù)同名, 且參數(shù)的類型、個數(shù)、順序必須且參數(shù)的類型、個數(shù)、順序必須(bx)一致,一致, 否則,屬于函數(shù)重載,而不是虛函數(shù)。否則,屬于函數(shù)重載,而不是虛函數(shù)。有關有關(yugun)虛函數(shù)的說虛函數(shù)的說明:明: (2)基類中虛函數(shù))基類中虛函數(shù)(hnsh)

50、前的關鍵字前的關鍵字virtual不能缺省。不能缺省。 (3)必須通過基類對象的)必須通過基類對象的指針或引用指針或引用調(diào)用虛函數(shù),調(diào)用虛函數(shù), 才能實現(xiàn)動態(tài)多態(tài)。才能實現(xiàn)動態(tài)多態(tài)。 (4)虛函數(shù)必須是類的成員函數(shù),不能是友元函數(shù),)虛函數(shù)必須是類的成員函數(shù),不能是友元函數(shù), 也不能是靜態(tài)成員函數(shù)。也不能是靜態(tài)成員函數(shù)。 (5)不能將構造函數(shù)定義為虛函數(shù),)不能將構造函數(shù)定義為虛函數(shù), 但可將析構函數(shù)定義為虛函數(shù)。但可將析構函數(shù)定義為虛函數(shù)。 (6)調(diào)用虛函數(shù)速度較慢。因為,要實現(xiàn)動態(tài)多態(tài),)調(diào)用虛函數(shù)速度較慢。因為,要實現(xiàn)動態(tài)多態(tài), 在函數(shù)調(diào)用處必須保留多個虛函數(shù)的入口地址。在函數(shù)調(diào)用處必須

51、保留多個虛函數(shù)的入口地址。第43頁/共57頁第四十四頁,共57頁。例例13.23 在成員函數(shù)中調(diào)用虛函數(shù)在成員函數(shù)中調(diào)用虛函數(shù)程序見程序見 “第第13章章 多態(tài)性多態(tài)性(例子例子).doc”,或閱讀或閱讀(yud)教材上的程序。教材上的程序。我們注意,我們注意,在成員函數(shù)中調(diào)用成員函數(shù)時,在成員函數(shù)中調(diào)用成員函數(shù)時,系統(tǒng)都是通過對象自身的指針系統(tǒng)都是通過對象自身的指針this調(diào)用的,調(diào)用的,A類中的類中的fun2( )的實際被處理成如下形式:的實際被處理成如下形式:void fun2( ) cout A:fun2 fun3( ); /EB b;b.fun1( ); / 調(diào)用調(diào)用A類的類的fun

52、1( )和和fun2( ),在,在A類的類的fun2( )函數(shù)中,函數(shù)中, / 在在E行行, this 是指向是指向(zh xin)b的指針的指針, 所以調(diào)用所以調(diào)用B的的fun3( )函數(shù)函數(shù)第44頁/共57頁第四十五頁,共57頁。class Apublic: A( ) fun( ); virtual void fun( ) cout A:fun t; ;class B: public A public: B( ) fun( ); void fun( ) cout B:fun t; void g( ) fun( ); / 在成員在成員(chngyun)函數(shù)中調(diào)用虛函數(shù)函數(shù)中調(diào)用虛函數(shù); A

53、B C 例例13.24 在構造函數(shù)中調(diào)用在構造函數(shù)中調(diào)用(dioyng)虛函數(shù)虛函數(shù)第45頁/共57頁第四十六頁,共57頁。class C: public B public:C( ) fun( ); void fun( ) cout C:fun n; ;void main( ) C c; /依次依次(yc)調(diào)用調(diào)用A、B、C三類的缺省構造函數(shù)三類的缺省構造函數(shù) c.g( );運行運行(ynxng)結果:結果:A:fun B:fun C:funC:fun構造函數(shù)調(diào)用虛函數(shù),調(diào)用的是類本身的虛函數(shù)。構造函數(shù)調(diào)用虛函數(shù),調(diào)用的是類本身的虛函數(shù)。成員函數(shù)調(diào)用虛函數(shù),遵循成員函數(shù)調(diào)用虛函數(shù),遵循(zn

54、xn)動態(tài)多態(tài)性原則。動態(tài)多態(tài)性原則。ABC第46頁/共57頁第四十七頁,共57頁。13.4.2 虛析構函數(shù)虛析構函數(shù)(hnsh)如果類的構造函數(shù)中有動態(tài)申請如果類的構造函數(shù)中有動態(tài)申請(shnqng)的存儲空間,的存儲空間,在析構函數(shù)中應釋放該空間。在析構函數(shù)中應釋放該空間。此時,建議將析構函數(shù)定義為虛函數(shù),此時,建議將析構函數(shù)定義為虛函數(shù),以便實現(xiàn)通過基類的指針或引用以便實現(xiàn)通過基類的指針或引用撤消派生類對象時的多態(tài)性。撤消派生類對象時的多態(tài)性。 第47頁/共57頁第四十八頁,共57頁。#include class Achar *Aptr;public:A( ) Aptr = new ch

55、ar100; A( ) /析構函數(shù)析構函數(shù)(hnsh)不是虛函數(shù)不是虛函數(shù)(hnsh) delete Aptr; coutDelete Aptrendl; ;例例: 析構函數(shù)析構函數(shù)(hnsh)不是虛函數(shù)不是虛函數(shù)(hnsh)的情況的情況第48頁/共57頁第四十九頁,共57頁。class B : public A char *Bptr; public: B( ) Bptr=new char100; B( ) delete Bptr; coutDelete Bptrendl; ;void main(void)B b; 輸出輸出(shch)結果:結果:Delete BptrDelete Aptr系統(tǒng)自動撤銷系統(tǒng)自動撤銷(chxio)派生類對象派生類對象,不需要將析構函數(shù)定義為虛函數(shù)。不需要將析構函數(shù)定義為虛函數(shù)。第49頁/共57頁第五十頁,共57頁。void main(void)A *p=new B; delete p;A &p1=*(new B); delete &p1;輸出輸出(shch)結果:結果:Delete AptrDelete Aptr如果將析構函數(shù)定義成虛析構函

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論