第五章 多態(tài)性與虛函數(shù)_第1頁
第五章 多態(tài)性與虛函數(shù)_第2頁
第五章 多態(tài)性與虛函數(shù)_第3頁
第五章 多態(tài)性與虛函數(shù)_第4頁
第五章 多態(tài)性與虛函數(shù)_第5頁
已閱讀5頁,還剩56頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、IC-MSP V1.0第五章第五章多態(tài)性和虛函數(shù) 手機(jī)移動(dòng)設(shè)備嵌入式C+ IC-MSP V1.0q基類和派生類q單繼承q多繼承 q虛基類回顧IC-MSP V1.0目標(biāo)q多態(tài)的概念q函數(shù)重載q運(yùn)算符重載 q了解靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編 q虛函數(shù) q理解抽象類的概念和用法IC-MSP V1.0程序的多態(tài)性程序的多態(tài)性 比如:C語言中的運(yùn)算符”/”對(duì)于不同的數(shù)據(jù)類型具有不同的含義。 6/4=1 6.0/4=1.5 6/4.0=1.5 6.0/4.0=1.5 程序中同一符號(hào)或名字在不同情況下具有不同解釋的現(xiàn)象稱為多態(tài)性。面向?qū)ο蟮亩鄳B(tài):面向?qū)ο蟮亩鄳B(tài):在面向?qū)ο笾校鄳B(tài)性是指發(fā)出同樣的消息被不同類型的對(duì)象接

2、收時(shí)導(dǎo)致完全不同的行為多態(tài)性的基本概念I(lǐng)C-MSP V1.0多態(tài)的種類q 編譯時(shí)多態(tài)編譯時(shí)多態(tài) 是指在程序編譯階段即可確定下來的多態(tài)性,主要通過重載機(jī)制獲得。包括函數(shù)重載和運(yùn)算符重載。q 運(yùn)行時(shí)多態(tài)運(yùn)行時(shí)多態(tài) 是指必須等到程序動(dòng)態(tài)運(yùn)行時(shí)才可確定的多態(tài),主要通過繼承結(jié)合虛函數(shù)來完成的。普通函數(shù)使用靜態(tài)綁定,而虛函數(shù)使用動(dòng)態(tài)綁定。IC-MSP V1.0函數(shù)重載 C+語言中,只要在聲明函數(shù)原型時(shí)形式參數(shù)的個(gè)數(shù)或者對(duì)應(yīng)位置的類型不同,兩個(gè)或更多的函數(shù)就可以共用同一個(gè)名字。這種在同一作用域中允許多個(gè)函數(shù)使用同一函數(shù)名的措施稱為重載。函數(shù)重載的方法 int abs(int x) double abs(do

3、uble x) long abs(long x) main() abs(-5); abs(-5L); abs(3.14); 函數(shù)重載IC-MSP V1.0 1. 在一個(gè)類中說明的重載在一個(gè)類中說明的重載 在一個(gè)類中說明的重載函數(shù)之間靠所帶參數(shù)個(gè)數(shù)或參數(shù)類型的不同加以區(qū)分class point int x,y; public: point()x=0;y=0; point(int x,int y) point:x=x;point:y=y; point(int i) x=y=i; ; void main() point p1; point p2(2,3); point p3(6); 函數(shù)重載方式IC

4、-MSP V1.0 2. 基類成員函數(shù)在派生類中重載基類成員函數(shù)在派生類中重載 在基類和派生類中的重載函數(shù)時(shí),編譯時(shí)根據(jù)下面兩種形式區(qū)分:(1)使用“類名類名:”加以區(qū)分(2) 根據(jù)調(diào)用函數(shù)對(duì)象調(diào)用函數(shù)對(duì)象加以區(qū)分。函數(shù)重載方式IC-MSP V1.0#include class point int x,y; public: point(int x,int y) point:x=x; point:y=y; float area() return 0.0; ; class circle:public point int r; public: circle(int x,int y,int r1):p

5、oint(x,y) r=r1; float area() return 3.14*r*r; ; void main() point p1(10,10); circle c1(5,5,10); cout p1.area() n; /根據(jù)調(diào)用函數(shù)對(duì)象加以區(qū)分根據(jù)調(diào)用函數(shù)對(duì)象加以區(qū)分 cout c1.area() endl; cout c1.point:area() endl;/使用使用“類名類名:”加以區(qū)分加以區(qū)分 示例IC-MSP V1.0不要使用重載函數(shù)來描述毫無相干的函數(shù)構(gòu)造函數(shù)可以重載,普通成員函數(shù)也可以重載如果兩個(gè)函數(shù)的參數(shù)表相同,但是返回類型不同,則第一個(gè)聲明被視為第一個(gè)的錯(cuò)誤重復(fù)聲明

6、,會(huì)被標(biāo)記為編譯錯(cuò)誤 unsigned int Max( int i1, int i2 ); int Max( int , int ); / 錯(cuò)誤:只有返回類型不同在重載函數(shù)中使用缺省函數(shù)參數(shù)時(shí)應(yīng)注意調(diào)用的二義性,例如:void print(int a, int b) cout a= a ,b= b endl;void print(int a, int b, int c = 50) cout a= a ,b= b endl; 下列函數(shù)調(diào)用,由于二義性將通不過:print(10,100);函數(shù)重載應(yīng)注意問題IC-MSP V1.0運(yùn)算符重載IC-MSP V1.0 C+中預(yù)定義的運(yùn)算符運(yùn)算符的操作對(duì)

7、象只能是基本數(shù)據(jù)類型基本數(shù)據(jù)類型,如果我們要想用“+”來實(shí)現(xiàn)兩個(gè)復(fù)數(shù)的求和運(yùn)算,怎么來實(shí)現(xiàn)呢? 比如說:我們定義了一個(gè)復(fù)數(shù)類complex class complex public:complex(double r=0.0,double I=0.0) real=r;imag=I; void display(); private: double real; double imag; ;問題的提出IC-MSP V1.0 那么可以這樣定義兩個(gè)復(fù)數(shù)類的對(duì)象: complex a(10,20),b(5,8); 那么用a+b是否可以得到這兩個(gè)復(fù)數(shù)的和呢? IC-MSP V1.0運(yùn)算符重載的規(guī)則如下: 幾乎

8、所有的運(yùn)算符都可以用作重載,下列運(yùn)算符不允許重載:.,*,: ,?:,# 重載之后運(yùn)算符的優(yōu)先級(jí)和結(jié)合性都不會(huì)改變。 運(yùn)算符重載是針對(duì)新類型數(shù)據(jù)的實(shí)際需要,對(duì)原有運(yùn)算符進(jìn)行適當(dāng)?shù)母脑?。一般來講,重載的功能應(yīng)當(dāng)與原有功能相類似,不能改變?cè)\(yùn)算符的操作對(duì)象個(gè)數(shù),同時(shí)至少要有一個(gè)操作對(duì)象是自定義類型。 運(yùn)算符重載概述IC-MSP V1.0運(yùn)算符的重載形式有兩種:重載為類的成員函數(shù)重載為類的友元函數(shù)。運(yùn)算符重載為類的成員函數(shù)的語法形式如下: operator (); friend operator ();運(yùn)算符重載的實(shí)現(xiàn)IC-MSP V1.0 q重載函數(shù)為類的成員函數(shù)的格式如下: operator (

9、)q表達(dá)式 c1 + c2 被編譯程序解釋為: c1.operator+(c2)q重載函數(shù)為類成員函數(shù)時(shí),總隱含了一個(gè)參數(shù),該參數(shù)為this指針q對(duì)雙目運(yùn)算符,有一個(gè)參數(shù);對(duì)單目運(yùn)算符,不再顯式說明參數(shù) 運(yùn)算符重載運(yùn)算符重載IC-MSP V1.0#include class complex public: complex(double r=0.0,double i=0.0) real=r;imag=i; complex operator +(complex c2); complex operator -(complex c2); void display(); private: double

10、real; double imag; ;實(shí)例(續(xù))IC-MSP V1.0complex complex:operator +(complex c2) /當(dāng)使用成員函數(shù)重載運(yùn)算符時(shí),雙目運(yùn)算符僅有一個(gè)參數(shù),/與一般成員函數(shù)一樣,運(yùn)算符函數(shù)中隱含有this指針,用于指向/調(diào)用該成員函數(shù)的對(duì)象。 return complex(real+c2.real,imag+c2.imag); /創(chuàng)建一個(gè)臨時(shí)無名對(duì)象作為返回值 complex complex:operator (complex c2) return complex(real-c2.real,imag-c2.imag); void complex:

11、display() cout(real,imag)endl; 實(shí)例(續(xù))IC-MSP V1.0void main() complex c1(5,4),c2(2,10),c3; cout“c1=”;c1.display(); cout“c2=”;c2.display(); c3=c1-c2; /c1.operator-(c2); cout“c3=c1-c2=”; c3.display(); c3=c1+c2; /c1.operator +(c2) cout“c3=c1+c2”; c3.display(); 實(shí)例(續(xù))IC-MSP V1.0q重載為友元函數(shù)的定義格式如下:friend operat

12、or ()q表達(dá)式 c1 + c2 被編譯程序解釋為: operator+(c1,c2)q當(dāng)重載友元函數(shù)時(shí),將沒有隱含的參數(shù) this 指針q對(duì)雙目運(yùn)算符,友元函數(shù)有兩個(gè)參數(shù);對(duì)單目運(yùn)算符,友元函數(shù)有一個(gè)參數(shù)q不能重載為友元函數(shù)的運(yùn)算符是:,(), 和 - 重載為友元函數(shù)重載為友元函數(shù)IC-MSP V1.0例:復(fù)數(shù)類加減法運(yùn)算重載友元函數(shù)形式#include class complex public: complex(double r=0.0,double i=0.0) real=r;imag=i;friend complex operator +(complex c1,complex c2)

13、;friend complex operator (complex c1,complex c2); 示例IC-MSP V1.0 void display(); private: double real;double imag; ; void complex:display() cout“(“real“,”imag”)”endl; complex operator +(complex c1,complex c2) return complex(c2.real+c1.real,c2.imag+c1.imag); complex operator (complex c1,complex c2) re

14、turn complex(c1.real-c2.real,c1.imag-c2.imag);IC-MSP V1.0 void main() complex c1(5,4),c2(2,10),c3; cout“c1=”;c1.display(); cout“c2=”;c2.display(); c3=c1-c2; cout“c3=c1-c2=”; c3.display(); c3=c1+c2; cout“c3=c1+c2=”; c3.display(); IC-MSP V1.0q 單目運(yùn)算符最好被重載為成員函數(shù);對(duì)雙目運(yùn)算符最好被重載為友元函數(shù)q 考慮一個(gè)表達(dá)式: 5.67 + c 重載為友元函

15、數(shù)時(shí),該表達(dá)式將被解釋為: operator+(complex (5.67), c) V 重載為成員函數(shù)時(shí),該表達(dá)式將被解釋為: 5.67.oprator+(c) Xq 有的雙目運(yùn)算符重載為成員函數(shù)為好,例如,賦值運(yùn)算符兩種重載形式的比較兩種重載形式的比較IC-MSP V1.0#include class A public: A( )X = Y = 0; A(int i, int j)X = i; Y = j; A(A &p)X = p.X; Y = p.Y; A& operator = (A &p); int getX( )return X; int getY( )return Y; pri

16、vate: int X, Y;賦值運(yùn)算符重載IC-MSP V1.0A& A:operator = (A &p) X = p.X; Y = p.Y; cout Assigment operator called.n; return *this;void main( ) A a(7, 8); A b; b = a; cout b.getX( ) , b.getY( ) endl;IC-MSP V1.0后綴運(yùn)算看作雙目運(yùn)算符: obj+ 看作 obj+0#include class counter public: counter( )v = 0; counter operator +( );/前置

17、counter operator +( int);/ 后置 void print( ) cout v endl; private: unsigned v;重載+運(yùn)算符IC-MSP V1.0counter counter : operator +( ) v+; return *this;counter counter : operator +(int) counter t; t.v = v+; return t;void main( ) counter c; for(int i = 0; i 8; i+) c+; c.print( ); for(i = 0; i 8; i+) +c; c.pri

18、nt( );IC-MSP V1.0數(shù)學(xué)函數(shù)的抽象:f(x,y) = (x+5)*y#include class F public: double operator ( ) (double x, double y) const;double F : operator ( )(double x, double y) const return (x + 5) * y; / (1.5+5)*2.2void main( )( F f; cout f( 1.5, 2.2) endl;重載()運(yùn)算符IC-MSP V1.0運(yùn)算符的重載實(shí)際上是函數(shù)的重載,對(duì)運(yùn)算符重載的選擇,遵循著函數(shù)重載的選擇原則重載運(yùn)算符有

19、以下各種限制:不可臆造新的運(yùn)算符 不能改變運(yùn)算符操作數(shù)的個(gè)數(shù); 不能改變運(yùn)算符原有的優(yōu)先級(jí); 不能改變運(yùn)算符原有的結(jié)合性; 不能改變運(yùn)算符原有的語法結(jié)構(gòu)運(yùn)算符重載的幾個(gè)問題運(yùn)算符重載的幾個(gè)問題IC-MSP V1.0靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編IC-MSP V1.0聯(lián)編是指一個(gè)計(jì)算機(jī)程序自身彼此關(guān)聯(lián)的過程聯(lián)編可以分為兩種不同的聯(lián)編方法:靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編IC-MSP V1.0靜態(tài)聯(lián)編是指聯(lián)編工作出現(xiàn)在編譯連接階段,又稱為早期聯(lián)編、靜態(tài)束定在編譯時(shí)就解決了程序中的操作調(diào)用與執(zhí)行該操作代碼間的關(guān)系靜態(tài)聯(lián)編靜態(tài)聯(lián)編IC-MSP V1.0include class Point public: P

20、oint(double i, double j)x=i;y=j; double Area( ) constreturn 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;示例IC-MSP V1.0Rectangle:Rectanagle(double i, double j, double k, double l)

21、 :Point(i,j) w = k; h = l;void fun(Point &s) cout s.Area( ) endl;void main( ) Rectangle rec(3.0, 5.2, 15.0, 25.0); fun(rec);示例(續(xù))IC-MSP V1.0程序在編譯階段并不能確切知道將要調(diào)用的函數(shù),只有在程序執(zhí)行時(shí)才能確定將要調(diào)用的函數(shù)這種在程序運(yùn)行時(shí)進(jìn)行聯(lián)編工作被稱為動(dòng)態(tài)聯(lián)編,或稱動(dòng)態(tài)束定,又叫晚期聯(lián)編靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編都是屬于多態(tài)性的,是在不同階段對(duì)不同實(shí)現(xiàn)進(jìn)行不同的選擇聯(lián)編是對(duì)這個(gè)引用的多態(tài)性的選擇,是對(duì)fun( )函數(shù)參數(shù)的多態(tài)性的選擇動(dòng)態(tài)聯(lián)編動(dòng)態(tài)聯(lián)編IC-MS

22、P V1.0虛函數(shù)是動(dòng)態(tài)聯(lián)編的基礎(chǔ)虛函數(shù)是非 static 的成員函數(shù)虛函數(shù)說明的方法如下: Virtual ()某類中的成員函數(shù)被說明為虛函數(shù),意味著該成員函數(shù)在派生類中可能有不同的實(shí)現(xiàn)當(dāng)使用這個(gè)成員函數(shù)操作指針或引用所標(biāo)識(shí)對(duì)象時(shí),該成員函數(shù)調(diào)用采取動(dòng)態(tài)聯(lián)編方式虛函數(shù)虛函數(shù)IC-MSP V1.0#include class Point public: Point(double i, double j)x = i; y = j; virtual double Area( ) return 0.0; private: double x,y;class Rectangle : public Poi

23、nt public: Rectangle(double i, double j ,double k, double l); virtual double Area( ) return w*h; private: double w, h;動(dòng)態(tài)聯(lián)編示例動(dòng)態(tài)聯(lián)編示例IC-MSP V1.0Rectangle:Rectanagle(double i,double j,double k,double l) : Point(i,j) w = k; h = l;void fun(Point &s) cout s.Area( ) endl;void main( ) Rectangle rec(3.0, 5.2,

24、 15.0, 25.0); fun(rec);動(dòng)態(tài)聯(lián)編示例(續(xù))動(dòng)態(tài)聯(lián)編示例(續(xù))IC-MSP V1.0派生類對(duì)派生類對(duì)基類虛函數(shù)基類虛函數(shù)進(jìn)行替換(覆蓋進(jìn)行替換(覆蓋)時(shí),滿足如下條件:時(shí),滿足如下條件:與基類的虛函數(shù)有相同的參數(shù)個(gè)數(shù)參數(shù)的類型與基類的虛函數(shù)的對(duì)應(yīng)參數(shù)類型相同其返回值或者與基類虛函數(shù)的相同,或者都返回指針或引用,并且派生類虛函數(shù)所返回的指針或引用的類型是基類中被替換的虛函數(shù)所返回的指針或引用的基類型子類型。滿足上述條件的派生類的成員函數(shù),自然是虛函數(shù),可以不必加 virtual 說明 說明IC-MSP V1.0分析程序,回答問題:分析程序,回答問題:#include clas

25、s A public: virtual void act1( ); void act2( ) act1( );void A:act1( ) cout A:act1( ) called. endl;示例IC-MSP V1.0class B : public A public: void act1( );void B : act1( ) cout B:act1( ) called act1( );輸出結(jié)果如何?IC-MSP V1.03. 如果將如果將A:act2( )的實(shí)現(xiàn)改為的實(shí)現(xiàn)改為: void A:act2( ) A:act1( );輸出結(jié)果如何?IC-MSP V1.0運(yùn)行過程中的多態(tài)需要滿

26、足三個(gè)條件: 1.類之間應(yīng)滿足賦值兼容規(guī)則。 2.要聲明虛函數(shù)。 3.要由成員函數(shù)來調(diào)用或者是通過指針、引用來訪問虛函數(shù)。 例:虛函數(shù)成員 #include class B0 public:virtual void display() cout“B0:display()”endl; ; IC-MSP V1.0 class B1:public B0 public:void display() cout“B1:display()”endl; ; class D1:public B1 public:void display() cout“D1:display()”display(); IC-MSP

27、V1.0 void main() B0 b0,*p; B1 b1; D1 d1; p=&b0; fun(p); p=&b1; fun(p); p=&d1; fun(p); B0(display)B1(display)D1(display)IC-MSP V1.0 注意:系統(tǒng)如何判斷一個(gè)函數(shù)成員是不是虛函數(shù)? 1.該函數(shù)是否與基類的虛函數(shù)有相同的名稱。 2.該函數(shù)是否與基類的虛函數(shù)有相同的參數(shù) 個(gè)數(shù)及相同的對(duì)應(yīng)參數(shù)類型。 3.該函數(shù)是否與基類的虛函數(shù)有相同的返回 值或者滿足賦值兼容性原則的指針、引用 型的返回值。 IC-MSP V1.0純虛函數(shù)與抽象類IC-MSP V1.0 q 一般格式如下: c

28、lass virtual () = 0; ;q 在基類中不能對(duì)虛函數(shù)給出有意義的實(shí)現(xiàn),把它說明為純虛函數(shù),它的實(shí)現(xiàn)留給該基類的派生類去做純虛函數(shù)純虛函數(shù)IC-MSP V1.0#include class point public: point(int i = 0, int j = 0)x0 = i; y0 = j; virtual void set( ) = 0; virtual void draw( ) = 0; protected: int x0, y0;使用純虛函數(shù)使用純虛函數(shù)IC-MSP V1.0class line : public point public: line(int i=

29、0, int j=0, int m=0, int n=0) : point(i, j) x1 = m; y1 = n; void set( )cout line:set( ) called.n; void draw( )cout line:draw( ) called.n; protected: int x1, y1;class ellipse : public point public: ellipse(int i=0, int j=0, int p=0, int q=0) : point(i,j) x2 = p; y2 = q; void set( )cout ellipse:set( ) called.n; void draw( )cout draw( );void setobj(point *p) p-set( );void main( ) line *lineobj = new line; ellipse *elliobj = new ellipse; drawobj(lineobj); drawobj(elliobj); cout endl; setobj(lineobj); setobj(elliobj); cout nRedraw the object

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論