清華大學經(jīng)典C++教程-鄭莉-8.ppt_第1頁
清華大學經(jīng)典C++教程-鄭莉-8.ppt_第2頁
清華大學經(jīng)典C++教程-鄭莉-8.ppt_第3頁
清華大學經(jīng)典C++教程-鄭莉-8.ppt_第4頁
清華大學經(jīng)典C++教程-鄭莉-8.ppt_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、1,第八章 多態(tài)性,清華大學 鄭 莉,C+語言程序設計,2,本章主要內(nèi)容,多態(tài)性 運算符重載 虛函數(shù) 純虛函數(shù) 抽象類,3,多態(tài)性的概念,多態(tài)性是面向對象程序設計的重要特征之一。 多態(tài)性是指發(fā)出同樣的消息被不同類型的對象接收時有可能導致完全不同的行為。 多態(tài)的實現(xiàn): 函數(shù)重載 運算符重載 虛函數(shù),4,問題舉例復數(shù)的運算,class complex/復數(shù)類聲明 public: complex(double r=0.0,double i=0.0) /構造函數(shù) real=r; imag=i; void display();/顯示復數(shù)的值 private: double real; double im

2、ag; ;,運算符重載,5,問題舉例復數(shù)的運算,用“+”、“-”能夠實現(xiàn)復數(shù)的加減運算嗎? 實現(xiàn)復數(shù)加減運算的方法 重載“+”、“-”運算符,運算符重載,6,運算符重載的實質,運算符重載是對已有的運算符賦予多重含義 必要性 C+中預定義的運算符其運算對象只能是基本數(shù)據(jù)類型,而不適用于用戶自定義類型(如類) 實現(xiàn)機制 將指定的運算表達式轉化為對運算符函數(shù)的調(diào)用,運算對象轉化為運算符函數(shù)的實參。 編譯系統(tǒng)對重載運算符的選擇,遵循函數(shù)重載的選擇原則。,運算符重載,7,運算符重載,規(guī)則和限制,可以重載C+中除下列運算符外的所有運算符:. .* : ?: 只能重載C+語言中已有的運算符,不可臆造新的。

3、不改變原運算符的優(yōu)先級和結合性。 不能改變操作數(shù)個數(shù)。 經(jīng)重載的運算符,其操作數(shù)中至少應該有一個是自定義類型。,8,兩種形式,重載為類成員函數(shù)。 重載為友元函數(shù)。,運算符重載,9,運算符函數(shù),聲明形式 函數(shù)類型 operator 運算符(形參) . 重載為類成員函數(shù)時 參數(shù)個數(shù)=原操作數(shù)個數(shù)-1(后置+、-除外) 重載為友元函數(shù)時 參數(shù)個數(shù)=原操作數(shù)個數(shù),且至少應該有一個自定義類型的形參。,運算符重載,10,運算符成員函數(shù)的設計,雙目運算符 B 如果要重載 B 為類成員函數(shù),使之能夠實現(xiàn)表達式 oprd1 B oprd2,其中 oprd1 為A 類對象,則 B 應被重載為 A 類的成員函數(shù),形

4、參類型應該是 oprd2 所屬的類型。 經(jīng)重載后,表達式 oprd1 B oprd2 相當于 oprd1.operator B(oprd2),運算符重載,11,運算符重載,例 8.1,將“+”、“-”運算重載為復數(shù)類的成員函數(shù)。 規(guī)則: 實部和虛部分別相加減。 操作數(shù): 兩個操作數(shù)都是復數(shù)類的對象。,#include using namespace std; class complex/復數(shù)類聲明 public:/外部接口 complex(double r=0.0,double i=0.0)real=r;imag=i; /構造函數(shù) complex operator + (complex c2)

5、; /+重載為成員函數(shù) complex operator - (complex c2); /-重載為成員函數(shù) void display();/輸出復數(shù) private:/私有數(shù)據(jù)成員 double real;/復數(shù)實部 double imag;/復數(shù)虛部 ;,12,complex complex:operator +(complex c2) /重載函數(shù)實現(xiàn) complex c; c.real=c2.real+real; c.imag=c2.imag+imag; return complex(c.real,c.imag); ,13,complex complex:operator -(compl

6、ex c2) /重載函數(shù)實現(xiàn) complex c; c.real=real-c2.real; c.imag=imag-c2.imag; return complex(c.real,c.imag); ,14,void complex:display() cout(real,imag)endl; void main() /主函數(shù) complex c1(5,4),c2(2,10),c3; /聲明復數(shù)類的對象 coutc1=; c1.display(); coutc2=; c2.display(); c3=c1-c2;/使用重載運算符完成復數(shù)減法 coutc3=c1-c2=; c3.display()

7、; c3=c1+c2;/使用重載運算符完成復數(shù)加法 coutc3=c1+c2=; c3.display(); ,15,程序輸出的結果為: c1=(5,4) c2=(2,10) c3=c1-c2=(3,-6) c3=c1+c2=(7,14),16,17,運算符成員函數(shù)的設計,前置單目運算符 U 如果要重載 U 為類成員函數(shù),使之能夠實現(xiàn)表達式 U oprd,其中 oprd 為A類對象,則 U 應被重載為 A 類的成員函數(shù),無形參。 經(jīng)重載后,表達式 U oprd 相當于 oprd.operator U(),運算符重載,18,運算符成員函數(shù)的設計,后置單目運算符 +和- 如果要重載 +或-為類成員

8、函數(shù),使之能夠實現(xiàn)表達式 oprd+ 或 oprd- ,其中 oprd 為A類對象,則 +或- 應被重載為 A 類的成員函數(shù),且具有一個 int 類型形參。 經(jīng)重載后,表達式 oprd+ 相當于 oprd.operator +(0),運算符重載,19,例8.2,運算符前置+和后置+重載為時鐘類的成員函數(shù)。 前置單目運算符,重載函數(shù)沒有形參,對于后置單目運算符,重載函數(shù)需要有一個整型形參。 操作數(shù)是時鐘類的對象。 實現(xiàn)時間增加1秒鐘。,運算符重載,/8_2.cpp #include using namespace std; class Clock/時鐘類聲明 public:/外部接口 Clock

9、(int NewH=0, int NewM=0, int NewS=0); void ShowTime(); Clock,20,Clock ,21,/后置單目運算符重載 Clock Clock:operator +(int) /注意形參表中的整型參數(shù) Clock old=*this; +(*this); return old; ,22,/其它成員函數(shù)的實現(xiàn)略 void main() Clock myClock(23,59,59); coutFirst time output:; myClock.ShowTime(); coutShow myClock+:; (myClock+).ShowTim

10、e(); coutShow +myClock:; (+myClock).ShowTime(); ,23,程序運行結果為: First time output: 23:59:59 Show myClock+: 23:59:59 Show +myClock: 0:0:1,24,25,運算符友元函數(shù)的設計,如果需要重載一個運算符,使之能夠用于操作某類對象的私有成員,可以此將運算符重載為該類的友元函數(shù)。 函數(shù)的形參代表依自左至右次序排列的各操作數(shù)。 后置單目運算符 +和-的重載函數(shù),形參列表中要增加一個int,但不必寫形參名。,運算符重載,26,運算符友元函數(shù)的設計,雙目運算符 B重載后,表達式opr

11、d1 B oprd2 等同于operator B(oprd1,oprd2 ) 前置單目運算符 B重載后,表達式 B oprd 等同于operator B(oprd ) 后置單目運算符 +和-重載后,表達式 oprd B 等同于operator B(oprd,0 ),運算符重載,27,例8-3,將+、-(雙目)重載為復數(shù)類的友元函數(shù)。 兩個操作數(shù)都是復數(shù)類的對象。,運算符重載,#include using namespace std; class complex/復數(shù)類聲明 public:/外部接口 complex(double r=0.0,double i=0.0) real=r; imag=

12、i; /構造函數(shù) friend complex operator + (complex c1,complex c2);/運算符+重載為友元函數(shù) friend complex operator - (complex c1,complex c2);/運算符-重載為友元函數(shù) void display();/顯示復數(shù)的值 private:/私有數(shù)據(jù)成員 double real; double imag; ;,28,complex operator +(complex c1,complex c2)/運算符重載友元函數(shù)實現(xiàn) return complex(c2.real+c1.real, c2.imag+c

13、1.imag); complex operator -(complex c1,complex c2)/運算符重載友元函數(shù)實現(xiàn) return complex(c1.real-c2.real, c1.imag-c2.imag); / 其它函數(shù)和主函數(shù)同例8.1,29,30,靜態(tài)綁定與動態(tài)綁定,綁定 程序自身彼此關聯(lián)的過程,確定程序中的操作調(diào)用與執(zhí)行該操作的代碼間的關系。 靜態(tài)綁定(靜態(tài)聯(lián)編) 聯(lián)編工作出現(xiàn)在編譯階段,用對象名或者類名來限定要調(diào)用的函數(shù)。 動態(tài)綁定 聯(lián)編工作在程序運行時執(zhí)行,在程序運行時才確定將要調(diào)用的函數(shù)。,#include using namespace std; class P

14、oint public: Point(double i, double j) x=i; y=j; double Area() const return 0.0; private: double x, y; ; class Rectangle:public Point public: Rectangle(double i, double j, double k, double l); double Area() const return w*h; private: double w,h; ;,靜態(tài)綁定例,31,Rectangle:Rectangle(double i, double j, dou

15、ble k, double l) :Point(i,j) w=k; h=l; void fun(Point 運行結果: Area=0,32,#include using namespace std; class Point public: Point(double i, double j) x=i; y=j; virtual double Area() const return 0.0; private: double x, y; ; class Rectangle:public Point public: Rectangle(double i, double j, double k, dou

16、ble l); virtual double Area() const return w*h; private: double w,h; ; /其它函數(shù)同例 8.8,動態(tài)綁定例,33,void fun(Point 運行結果: Area=375,34,35,虛函數(shù),虛函數(shù)是動態(tài)綁定的基礎。 是非靜態(tài)的成員函數(shù)。 在類的聲明中,在函數(shù)原型之前寫virtual。 virtual 只用來說明類聲明中的原型,不能用在函數(shù)實現(xiàn)時。 具有繼承性,基類中聲明了虛函數(shù),派生類中無論是否說明,同原型函數(shù)都自動為虛函數(shù)。 本質:不是重載聲明而是覆蓋。 調(diào)用方式:通過基類指針或引用,執(zhí)行時會根據(jù)指針指向的對象的類,決

17、定調(diào)用哪個函數(shù)。,虛 函 數(shù),36,例 8.4,#include using namespace std; class B0/基類B0聲明 public:/外部接口 virtual void display() /虛成員函數(shù) coutB0:display()endl; ; class B1: public B0/公有派生 public: void display() coutB1:display()endl; ; class D1: public B1/公有派生 public: void display() coutD1:display()endl; ;,虛 函 數(shù),void fun(B0 *

18、ptr)/普通函數(shù) ptr-display(); void main()/主函數(shù) B0 b0, *p;/聲明基類對象和指針 B1 b1;/聲明派生類對象 D1 d1;/聲明派生類對象 p=/調(diào)用派生類D1函數(shù)成員 ,運行結果: B0:display() B1:display() D1:display(),37,38,虛析構函數(shù),何時需要虛析構函數(shù)? 當你可能通過基類指針刪除派生類對象時 如果你打算允許其他人通過基類指針調(diào)用對象的析構函數(shù)(通過delete這樣做是正常的),并且被析構的對象是有重要的析構函數(shù)的派生類的對象,就需要讓基類的析構函數(shù)成為虛擬的。,虛 函 數(shù),39,抽象類,帶有純虛函數(shù)的類稱為抽象類: class 類名 virtual 類型 函數(shù)名(參數(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

提交評論