西安工業(yè)大學(xué)耿軍雪老師的C課件之多態(tài)性.ppt
《西安工業(yè)大學(xué)耿軍雪老師的C課件之多態(tài)性.ppt》由會員分享,可在線閱讀,更多相關(guān)《西安工業(yè)大學(xué)耿軍雪老師的C課件之多態(tài)性.ppt(95頁珍藏版)》請在裝配圖網(wǎng)上搜索。
Object Oriented,面向?qū)ο蠹夹g(shù)與C+,計算機學(xué)院,Object Oriented,5-0 分析結(jié)果?,#include class point double x,y; public : point (double i,double j) x=i;y=j; double area() return 0.0; ; class rectangle : public point double w,h; public : rectangle(double i,double j,double m,double n):point(i,j) w=m;h=n; double area() return w*h; ; void fun(point ,Object Oriented,第五章 多態(tài)性,本章主要內(nèi)容: 多態(tài)性 同一名稱,不同的功能實現(xiàn)方式 運算符重載 多態(tài)的經(jīng)典內(nèi)容 虛函數(shù) 動態(tài)綁定 純虛函數(shù) 統(tǒng)一接口 抽象類 定義一個框架,由其衍生對象完善,Object Oriented,一、多態(tài)性 多態(tài)性:是指不同對象在收到相同的消息時,產(chǎn)生不同的動作用同一個名字定義不同的函數(shù),執(zhí)行不同但相似的操作實現(xiàn)“一個接口,多種方法”。 多態(tài)的實現(xiàn): 函數(shù)重載:通過形參來區(qū)分 運算符重載:只是一種“語法修飾”,是專用格式的函數(shù)重載 虛函數(shù):冠以關(guān)鍵字 virtual 的成員函數(shù)稱為虛函數(shù),Object Oriented,二、聯(lián)編的概念及分類 1、聯(lián)編的概念 聯(lián)編:源程序經(jīng)過編譯、聯(lián)接成可執(zhí)行文件的過程 即將可執(zhí)行代碼聯(lián)編(裝配)在一起的過程。 2、聯(lián)編的分類: 靜態(tài)聯(lián)編(前期聯(lián)編):在運行前完成的聯(lián)編在編譯時完成(要求在編譯時就知道調(diào)用函數(shù)的全部信息)其優(yōu)點是“效率高”。(重載函數(shù)使用靜態(tài)聯(lián)編。) 動態(tài)聯(lián)編(后期聯(lián)編):在運行時才完成的聯(lián)編在程序運行時動態(tài)調(diào)用所需函數(shù)優(yōu)點是提供了更好的“靈活性”、問題的“抽象性”、程序的“易維護性”。(switch 語句和 if 語句是動態(tài)聯(lián)編的例子),Object Oriented,三、多態(tài)性的分類 編譯時多態(tài)性:靜態(tài)聯(lián)編支持的多態(tài)性(靜態(tài)多態(tài)性)通過函數(shù)重載及運算符重載實現(xiàn)。 運行時多態(tài)性:動態(tài)聯(lián)編支持的多態(tài)性(動態(tài)多態(tài)性)通過虛函數(shù)實現(xiàn)。 四、函數(shù)重載 同一個類中的同名函數(shù)參數(shù)個數(shù)不一樣、參數(shù)類型不一樣、參數(shù)個數(shù)及類型不一樣; 不同類中的同名函數(shù)通過類名調(diào)用或類的對象調(diào)用。 同一個類中同名的普通成員函數(shù)及常量成員函數(shù)通過const實現(xiàn)重載。,Object Oriented,第一節(jié) 虛函數(shù)和基類指針,冠以關(guān)鍵字 virtual 的成員函數(shù)稱為虛函數(shù) 實現(xiàn)運行時多態(tài)的關(guān)鍵首先是要說明虛函數(shù),另外,必須用基類指針調(diào)用派生類的不同實現(xiàn)版本 虛函數(shù)與派生類相結(jié)合,使C+能支持運行時多態(tài)性實現(xiàn)在基類中定義派生類所擁有的通用“接口”,而在派生類中定義具體的實現(xiàn)方法,即“一個接口,多種方法”。,Object Oriented,5-1,#include class Base public : Base(char xx) x = xx; void who() cout “Base class: “ x “n“ ; protected: char x; ; class First_d : public Base public : First_d(char xx, char yy):Base(xx) y = yy; void who() cout “First derived class: “ x “, “ y “n“ ; protected: char y; ; class Second_d : public First_d public : Second_d( char xx, char yy, char zz ) : First_d( xx, yy ) z = zz; void who() cout “Second derived class: “ x “, “ y “, “ z “n“ ; protected: char z; ;,Object Oriented,void main() Base B_obj( A ) ; First_d F_obj( T, O ) ; Second_d S_obj( E, N, D ) ; Base * p ; p = ,通過基類指針 只能訪問從基類繼承的成員,Object Oriented,5-2,#include class Base public : Base(char xx) x = xx; virtual void who() cout “Base class: “ x “n“ ; protected: char x; ; class First_d : public Base public : First_d(char xx, char yy):Base(xx) y = yy; void who() cout “First derived class: “ x “, “ y “n“ ; protected: char y; ; class Second_d : public First_d public : Second_d( char xx, char yy, char zz ) : First_d( xx, yy ) z = zz; void who() cout“Second derived class: “x“, “y“, “z“n“ ; protected: char z; ;,Object Oriented,void main() Base B_obj( A ) ; First_d F_obj( T, O ) ; Second_d S_obj( E, N, D ) ; Base * p ; p = ,由于who()的虛特性 隨著p指向不同對象,執(zhí)行不同實現(xiàn)版本,Object Oriented,注意: 一個虛函數(shù),在派生類層界面相同的重載函數(shù)都保持虛特性 虛函數(shù)必須是類的成員函數(shù),不能是全局函數(shù)和靜態(tài)函數(shù) 不能將友員說明為虛函數(shù),但虛函數(shù)可以是另一個類的友員 析構(gòu)函數(shù)可以是虛函數(shù),但構(gòu)造函數(shù)不能是虛函數(shù) 動態(tài)聯(lián)編只能通過指針或引用來操作虛函數(shù),如果采用其他標(biāo)識對象來操作虛函數(shù),將采用靜態(tài)聯(lián)編方式調(diào)用虛函數(shù)。,Object Oriented,虛析構(gòu)函數(shù),構(gòu)造函數(shù)不能是虛函數(shù)。建立一個派生類對象時,必須從類層次的根開始,沿著繼承路徑逐個調(diào)用基類的構(gòu)造函數(shù) 析構(gòu)函數(shù)可以是虛的。虛析構(gòu)函數(shù)用于指引 delete 運算符正確析構(gòu)動態(tài)對象,Object Oriented,5-3普通析構(gòu)函數(shù)在刪除動態(tài)派生類對象的調(diào)用情況,#include class A public: A() cout “A:A() is called.n“ ; ; class B : public A public: B() cout “B:B() is called.n“ ; ; void main() A *Ap = new B ;/用基類指針建立派生類的動態(tài)對象 B *Bp2 = new B ;/用派生類指針建立派生類的動態(tài)對象 cout “delete first object:n“ ; delete Ap;/析構(gòu)由基類指針建立的派生類對象沒有調(diào)用派生類構(gòu)造函數(shù)問題? cout “delete second object:n“ ; delete Bp2 ;/析構(gòu)由派生類指針建立的派生類對象正確調(diào)用派生類構(gòu)造函數(shù) ,Object Oriented,5-4虛析構(gòu)函數(shù)在刪除動態(tài)派生類對象的調(diào)用情況,#include class A public: virtual A() cout “A:A() is called.n“ ; ; class B : public A public: B() cout “B:B() is called.n“ ; ; void main() A *Ap = new B ; B *Bp2 = new B ; cout “delete first object:n“ ; delete Ap; cout “delete second object:n“ ; delete Bp2 ; ,定義了基類虛析構(gòu)函數(shù),基類指針指向的 派生類動態(tài)對象也可以正確地用delete析構(gòu) 設(shè)計類層次結(jié)構(gòu)時,提供一個虛析構(gòu)函數(shù), 能夠使派生類對象在不同狀態(tài)下正確調(diào)用析構(gòu)函數(shù),Object Oriented,第二節(jié) 純虛函數(shù)和抽象類,純虛函數(shù)是一個在基類中說明的虛函數(shù),為各派生類提供一個公共界面,在基類中沒有定義,要求任何派生類都定義自己的版本 純虛函數(shù) 純虛函數(shù)說明形式: virtual 類型 函數(shù)名(參數(shù)表)= 0 ; 一個具有純虛函數(shù)的基類稱為抽象類。,Object Oriented,class figure /figure.h protected : double x,y; 5-5 public: void set_dim(double i, double j=0) x = i ; y = j ; virtual void show_area() = 0 ; ; class triangle : public figure public : void show_area() cout“Triangle with high “x“ and base “y “ has an area of “x*0.5*y“n“; ; class square : public figure public: void show_area() cout“Square with dimension “x“*“y “ has an area of “x*y“n“; ; class circle : public figure public: void show_area() cout“Circle with radius “x; cout“ has an area of “3.14*x*x“n“; ;,Object Oriented,#include #include“figure.h“ void main() triangle t ; /派生類對象 square s ; circle c; t.set_dim(10.0,5.0) ; t.show_area(); s.set_dim(10.0,5.0) ; s.show_area() ; c.set_dim(9.0) ; c.show_area() ; ,抽象類至少有一個純虛函數(shù)。 如果抽象類的一個派生類沒有為繼承的純虛函數(shù)定義實現(xiàn)版本,則它仍然是抽象類。,Object Oriented,5-6,class point /*/ ; class shape ; / 抽象類 point center ; public : point where ( ) return center ; void move ( point p ) enter = p ; draw ( ) ; virtual void rotate ( int ) = 0 ; / 純虛函數(shù) virtual void draw ( ) = 0 ; / 純虛函數(shù) ; .,shape x ; / error,抽象類不能建立對象 shape *p ; / ok,可以聲明抽象類的指針 shape f ( ) ; / error, 抽象類不能作為返回類型 void g ( shape ) ; / error, 抽象類不能作為參數(shù)類型 shape / ok,可以聲明抽象類的引用,Object Oriented,class ab_circle : public shape int radius ; public : void rotate ( int ) ; ;,ab_circle 類仍為抽象類 ab_circle : draw ( ) 、ab_circle : rotate ( ) 也是純虛函數(shù),要使 ab_circle 成為非抽象類, 必須作以下說明: class ab_circle : public shape int radius ; public : void rotate ( int ) ; void draw ( ) ; ; 并提供 ab_circle : draw ( ) 和 ab_circle : rotate ( int ) 的定義,Object Oriented,5-7聲明抽象類指針,#include #include“figure.h“ void main() figure *p; / 聲明抽象類指針 triangle t; square s; circle c; p= ,Object Oriented,5-8抽象類引用,#include class Number public : Number (int i) val = i ; virtual void Show() = 0 ; protected: int val ; ; class Hex_type : public Number public: Hex_type(int i) : Number(i) void Show() cout “Hexadecimal:“ hex val endl ; ; class Dec_type : public Number public: Dec_type(int i) : Number(i) void Show() cout “Decimal: “ dec val endl ; ; class Oct_type : public Number public: Oct_type(int i) : Number(i) void Show() cout “Octal: “ oct val endl ; ;,Object Oriented,void fun( Number / Oct_type:Show() ,Object Oriented,應(yīng)用舉例求圓、圓的內(nèi)切正方形及外切正方形的面積及周長 #include #include class shape protected : double r; public: shape(double x) r=x; virtual double area()=0; virtual double perimeter()=0; ;,Object Oriented,class circle:public shape public: circle(double x):shape(x) double area() return 3.14*r*r; double perimeter() return 2*3.14*r; ; class in_square:public shape public: in_square(double x):shape(x) double area() return 2*r*r; double perimeter() return 4*sqrt(2)*r; ;,Object Oriented,class ex_square:public shape public: ex_square(double x):shape(x) double area() return 4*r*r; double perimeter() return 8*r; ; void main() shape *p; circle ob1(5.0); in_square ob2(5.0); ex_square ob3(5); p=,Object Oriented,第三節(jié) 運算符重載,運算符重載使得用戶自定義的數(shù)據(jù)以一種更簡潔的方式工作,就是賦予已有的運算符多重含義。,例如 int x , y ; y = x + y ;,matrix m1 , m2 ; / 矩陣類對象 m2 = Madd ( m1 , m2 ) ; / 調(diào)用函數(shù)計算兩個矩陣的和,complex c1 , c2 ; / 復(fù)數(shù)類對象 c1 = Cadd (c1 , c2 ) ; / 調(diào)用函數(shù)計算兩個復(fù)數(shù)的和,能表示為 c1 = c1 + c2 ; ?,能表示為 m1 = m1 + m2 ; ?,定義 運算符重載函數(shù),Object Oriented,類以外的運算符重載,#include class complex public : double real ; double imag; complex(double r=0,double i=0) real=r;imag=i; ; complex operator+(complex co1,complex co2)/運算符“+”的重載函數(shù) complex temp; temp.real=co1.real+co2.real; temp.imag=co1.imag+co2.imag; return temp; void main() complex com1(1.1,2.2),com2(3.3,4.4),total1,total2; total1=operator+(com1,com2);/運算符重載的使用方法1 cout “real1=“total1.real; cout“ imag1=“total1.imagendl; total2=com1+com2;/運算符重載的使用方法2 cout “real2=“total2.real; cout“ imag2=“total2.imagendl; ,Object Oriented,一、運算符重載的實質(zhì) 運算符重載是對已有的運算符賦予多重含義 必要性 C+中預(yù)定義的運算符其運算對象只能是基本數(shù)據(jù)類型,而不適用于用戶自定義類型(如類) 實現(xiàn)機制 將指定的運算表達式轉(zhuǎn)化為對運算符函數(shù)的調(diào)用,運算對象轉(zhuǎn)化為運算符函數(shù)的實參。 相當(dāng)于a+b = +(a,b) 編譯系統(tǒng)對重載運算符的選擇,遵循函數(shù)重載的選擇原則。 相當(dāng)于選+(1,2)還是+(1,1),(2,2)?,Object Oriented,二、重載運算符的限制 1、不能重載的算符 . : * ?: # sizeof 2、重載運算符可以對運算符作出新的解釋,但原有基本語義不變: 不改變運算符的優(yōu)先級和結(jié)合性。(否則難以記憶) 不改變運算符所需要的操作數(shù),即單目運算符只能重載為單目運算符,不能將單目運算符重載為雙目運算符。 不能創(chuàng)建新的運算符,只有系統(tǒng)預(yù)定義的運算符才能被重載。 經(jīng)重載的運算符,其操作數(shù)中至少應(yīng)該有一個是自定義類型。 (否則系統(tǒng)已經(jīng)實現(xiàn)了) 3、運算符通常是對類中的私有成員進行操作,故重載運算符應(yīng)能訪問類中的私有成員,所以重載運算符一般采用成員函數(shù)或友員函數(shù)的形式,Object Oriented,三、重載為類成員函數(shù) 語法形式為: 類型 類名 : operator op ( 參數(shù)表 ) / 相對于該類定義的操作 其中,當(dāng)為雙目運算符時,參數(shù)表中為一個參數(shù),單目運算符時,參數(shù)表為空通過this指針傳遞。,Object Oriented,(一)雙目運算符的重載 例【5.3.2】重載二個復(fù)數(shù)對象的加、減、乘、除運算符熟悉雙目運算符的重載。 1、分析:設(shè)兩個復(fù)數(shù)a+bi和c+di,則有: 加法:(a+bi)+(c+di)=(a+c)+(b+d)i; 減法:(a+bi)-(c+di)=(a-c)+(b-d)i; 乘法:(a+bi)*(c+di)=(ac-bd)+(ad+bc)i 除法:(a+bi)/(c+di)=(a+bi)*(c-di)/(c2+d2) =(ac+bd)/ (c2+d2)+(bc-ad)i/(c2+d2) 2、程序:,Object Oriented,#include class complex private : double real ; double imag; public : complex(double r=0,double i=0) real=r;imag=i; complex operator+(complex c); complex operator-(complex c); complex operator*(complex c); complex operator/(complex c); void print(); ;,Object Oriented,complex complex :operator+(complex c)/重載“+” complex temp; temp.real=real+c.real; temp.imag=imag+c.imag; return temp; complex complex :operator-(complex c)/重載“-” complex temp; temp.real=real-c.real; temp.imag=imag-c.imag; return temp; ,Object Oriented,complex complex :operator*(complex c)/重載“*” complex temp; temp.real=real*c.real-imag*c.imag; temp.imag=real*c.imag+imag*c.real; return temp; complex complex :operator/(complex c)/重載“/” complex temp; double t; t=c.real*c.real+c.imag*c.imag; temp.real=(real*c.real+imag*c.imag)/t; temp.imag=(c.real*imag-real*c.imag)/t; return temp; ,Object Oriented,void complex:print() cout 0) cout“+“; if (imag!=0) cout imag“i“endl; void main() complex A1(2.3,4.6),A2(3.6,2.8),A3,A4,A5,A6; A3=A1+A2;A4=A1-A2; A5=A1*A2;A6=A1/A2; A1.print();A2.print(); A3.print();A4.print(); A5.print();A6.print(); ,Object Oriented,(二)單目運算符重載(單目運算符重載時沒有參數(shù)。) 前置和后置,函數(shù)名都是operator +,所以人為給后置多加一個啞參數(shù),只有類型名。 例【5.3.3】運算符前置+和后置+重載為時鐘類的成員函數(shù)。 前置單目運算符,重載函數(shù)沒有形參,對于后置單目運算符,重載函數(shù)需要有一個整型形參。 操作數(shù)是時鐘類的對象。 實現(xiàn)時間增加1秒鐘。,Object Oriented,#include class Clock /時鐘類聲明 public: /外部接口 Clock(int NewH=0, int NewM=0, int NewS=0) Hour=NewH;Minute=NewM;Second=NewS; void ShowTime() coutHour“:“Minute“:“Secondendl; void operator +(); /前置單目運算符重載 void operator +(int); /后置單目運算符重載 private: /私有數(shù)據(jù)成員 int Hour, Minute, Second; ;,Object Oriented,void Clock:operator +( ) /前置單目運算符重載函數(shù) Second+; if(Second=60) /考慮進位 Second=Second-60; Minute+; if(Minute=60) Minute=Minute-60; Hour+; Hour=Hour%24; cout“+Clock: “; ,Object Oriented,void Clock:operator +(int) /后置單目運算符重載 Second+; if(Second=60) Second=Second-60; Minute+; if(Minute=60) Minute=Minute-60; Hour+; Hour=Hour%24; cout“Clock+: “; ,Object Oriented,void main() Clock myClock(23,59,59); cout“First time output:“; myClock.ShowTime(); myClock+; myClock.ShowTime(); +myClock; myClock.ShowTime(); ,Object Oriented,四、重載為友元函數(shù) 例【5.3.4】將+、-(雙目)重載為復(fù)數(shù)類的友元函數(shù)。 兩個操作數(shù)都是復(fù)數(shù)類的對象。 #include class complex private : double real ; double imag; public : complex(double r=0,double i=0) real=r;imag=i; void print(); friend complex operator+(complex a,complex b); friend complex operator-(complex a,complex b); friend complex operator*(complex a,complex b); friend complex operator/(complex a,complex b); ;,Object Oriented,complex operator+(complex a,complex b) complex temp; temp.real=a.real+b.real; temp.imag=a.imag+b.imag; return temp; complex operator-(complex a,complex b) complex temp; temp.real=a.real-b.real; temp.imag=a.imag-b.imag; return temp; ,Object Oriented,complex operator*(complex a,complex b) complex temp; temp.real=a.real*b.real-a.imag*b.imag; temp.imag=a.real*b.imag+a.imag*b.real; return temp; complex operator/(complex a,complex b) complex temp; double t; t=b.real*b.real+b.imag*b.imag; temp.real=(a.real*b.real+a.imag*b.imag)/t; temp.imag=(b.real*a.imag-a.real*b.imag)/t; return temp; ,Object Oriented,void complex:print() cout 0) cout“+“; if (imag!=0) cout imag“i“endl; void main() complex A1(2.3,4.6),A2(3.6,2.8),A3,A4,A5,A6; A3=A1+A2; A4=A1-A2; A5=A1*A2; A6=A1/A2; A1.print(); A2.print(); A3.print(); A4.print(); A5.print(); A6.print(); ,Object Oriented,重載為成員函數(shù),解釋為: Object . operator op () 操作數(shù)由對象Object通過this指針隱含傳遞 重載為友員函數(shù),解釋為: operator op (Object) 操作數(shù)由參數(shù)表的參數(shù)Object提供,1一元運算符,Object op 或 op Object,Object Oriented,重載為成員函數(shù),解釋為: ObjectL . operator op ( ObjectR ) 左操作數(shù)由ObjectL通過this指針傳遞,右操作數(shù)由參數(shù)ObjectR傳遞 重載為友員函數(shù),解釋為: operator op ( ObjectL, ObjectR ) 左右操作數(shù)都由參數(shù)傳遞,2二元運算符,ObjectL op ObjectR,Object Oriented,總結(jié) 運算符函數(shù)可以重載為成員函數(shù)或友員函數(shù) 關(guān)鍵區(qū)別在于成員函數(shù)具有 this 指針,友員函數(shù)沒有this指針 不管是成員函數(shù)還是友員函數(shù)重載,運算符的使用方法相同。但傳遞參數(shù)的方法不同,實現(xiàn)代碼不同,應(yīng)用場合也不同。 當(dāng)一元運算符的操作數(shù),或者二元運算符的左操作數(shù)是該類的一個對象時,定義重載運算符函數(shù)為成員函數(shù) 友員函數(shù)重載運算符常用于算符的左右操作數(shù)類型不同的情況,左操作數(shù)可以是常數(shù)或其他類型的數(shù)。 運算符=、( )、 、-不能用友元函數(shù)重載,(只能用成員函數(shù)重載),Object Oriented,class nclass private : int a ; int b ; public : nclass operator+(int x); ; nclass nclass : operator+(int x) nclass temp ; temp.a=a+x; temp.b=b+x; return temp; ,void main() nclass ob1,ob2; ob2=ob1+100; ob2=100+ob1; ,程序中: ob2=ob1+100;正確 ob2=100+ob1;不正確,為什么?,例【5.3.5】常數(shù)與復(fù)數(shù)相加。 #include class complex private : double real ; double imag; public : complex(double r=0,double i=0) real=r;imag=i; void show() cout “real=“real“ imag=“imagendl; friend complex operator+(complex co,double x); friend complex operator+(double x,complex co); ;,Object Oriented,complex operator+(complex co,double x) complex temp; temp.real=co.real+x; temp.imag=co.imag; return temp; complex operator+(double x,complex co) complex temp; temp.real=x+co.real; temp.imag=co.imag; return temp; void main() complex com1(1.1,2.2),com2,com3; com2=com1+10.0; com2.show(); com3=20.0+com1; com3.show(); ,Object Oriented,五、賦值運算符“=”的重載 同拷貝構(gòu)造函數(shù)一樣,通?!?”不用重載,同一類的對象可直接賦值。如:ob1=ob2; 當(dāng)在類中用new分配內(nèi)存空間,在析構(gòu)函數(shù)中用delete中釋放內(nèi)存空間時,應(yīng)重載“=”運算符。,例【5.3.6】調(diào)試下列程序,分析出錯的原因,#include #include class string char *ptr; public : string(char *s) ptr=new charstrlen(s)+1; strcpy(ptr,s); string() delete ptr; void print() cout ptrendl; ;,void main() string p1(“chen“); string p2(“ “); p2=p1; cout “p2: “; p2.print(); cout“p1: “; p1.print(); ,Object Oriented,void main() string p1(“chen“); string p2(“ “); p2=p1; cout “p2: “; p2.print(); cout“p1: “; p1.print(); ,Object Oriented,出錯原因分析:,Object Oriented,解決辦法:重載“=”運算符 例【5.3.7】將上例程序改為:,#include #include class string char *ptr; public : string(char *s) ptr=new charstrlen(s)+1; strcpy(ptr,s); string() delete ptr; void print() cout ptrendl; string ,Object Oriented,string ,說明: 類的賦值運算符“=”只能重載為成員函數(shù),重載后不能被繼承。,Object Oriented,注意:對象初始化時的賦值和已創(chuàng)建對象之間的賦值雖然都涉及對象的復(fù)制,但它們是兩個不同的操作。對象初始化首先是為新對象分配存儲空間,然后執(zhí)行對象復(fù)制。 如:Point p1, p2(3.14, 4.06); Point p3=p2; /調(diào)用拷貝構(gòu)造初始化函數(shù) p1=p2; /調(diào)用賦值運算符重載,Object Oriented,本章小結(jié),多態(tài): 同樣的消息被不同類型的對象接收時導(dǎo)致完全不同的行為,是對類的特定成員函數(shù)的再抽象。 運算符重載 對已有的運算符賦予多重含義,使用已有運算符對用戶自定義類型(比如類)進行運算操作。 聯(lián)編 程序自身彼此關(guān)聯(lián)的過程稱為聯(lián)編,聯(lián)編確定程序中的操作調(diào)用與執(zhí)行該操作的代碼間的關(guān)系。 靜態(tài)聯(lián)編工作出現(xiàn)在編譯階段。 動態(tài)聯(lián)編工作在程序運行時執(zhí)行。虛函數(shù)是動態(tài)聯(lián)編的基礎(chǔ)。,Object Oriented,純虛函數(shù) 在基類中說明的虛函數(shù),它在該基類中可以不給出函數(shù)體,要求各派生類根據(jù)實際需要編寫自己的函數(shù)體。 抽象類 帶有純虛函數(shù)的類是抽象類。 抽象類的主要作用是通過它為一個類族建立一個公共的接口,使它們能夠更有效地發(fā)揮多態(tài)特性。,Object Oriented,練習(xí),1、分別使用成員函數(shù)和友員函數(shù)編程序重載運算符“+”,使該運算符能實現(xiàn)兩個字符串的連接。,Object Oriented,#include“iostream.h“ #include class string public: string() *str = 0; string( char *pstr ) strcpy( str,pstr ); char *gets() return str; string operator+( string obj ); private: char str100; ; string string:operator+( string obj ) strcat( str,obj.str ); return str; /或return *this void main() string obj1( “Visual“ ),obj2( “ C+“ ),obj3; obj3 = obj1 + obj2; cout obj3.gets() endl; ,Object Oriented,#include #include class string public: string() *str= 0; string( char *pstr ) strcpy( str,pstr ); char *gets() return str; friend string operator+( string obj1,string obj2 ); private: char str100; ; string operator+( string obj1,string obj2 ) string tempobj; strcat( tempobj.str,obj1.str ); strcat( tempobj.str,obj2.str ); return tempobj; void main() string obj1( “Visual“ ),obj2( “ C+“ ),obj3; obj3 = obj1 + obj2; cout obj3.gets() endl; ,Object Oriented,Employee,抽象類 提供一般屬性,共同操作界面,管理人員類 提供特殊屬性,操作實現(xiàn),計時工人類 提供特殊屬性,操作實現(xiàn),計件工人類 提供特殊屬性,操作實現(xiàn),2.計算雇員工資,Object Oriented,class Employee public: Employee(long no, char* na); virtual Employee(); /虛析構(gòu)函數(shù) char * getName(); long getNumber(); virtual double earnings() =0; /純虛函數(shù),計算月薪 virtual void print(); /虛函數(shù),輸出編號、姓名 protected: long number; / 編號 char * name; / 姓名 ;,Object Oriented,3、異質(zhì)鏈表 程序中,用基類類型指針,可以生成一個連接不同派生類對象的動態(tài)鏈表,即每個結(jié)點指針可以指向類層次中不同的派生類對象。 這種結(jié)點類型不相同鏈表稱為異質(zhì)鏈表。,Object Oriented,class Employee public: Employee(long no, char* na); virtual Employee(); /虛析構(gòu)函數(shù) char * getName(); long getNumber(); virtual double earnings() =0; /純虛函數(shù),計算月薪 virtual void print(); /虛函數(shù),輸出編號、姓名 Employee *next ; protected: long number; / 編號 char * name; / 姓名 ;,Object Oriented,void AddFront( Employee * ,Object Oriented,for 1:,#include #include class Point public: Point(double xi, double yi) X = xi ; Y = yi ; double GetX() return X ; double GetY() return Y ; friend double Distance ( Point ,Object Oriented,for 2:類和對象,定義一個正方形類,該類包括: (1)受保護類數(shù)據(jù)成員,表示正方形類的邊長,取值范圍在1-30 (2)四個成員函數(shù),分別為: 帶參構(gòu)造函數(shù),初始化正方形邊長; 取邊長函數(shù)GetLen( ); 設(shè)置邊長函數(shù) SetLen( ),重新設(shè)置邊長,并檢查是否在規(guī)定范圍內(nèi); 畫正方形函數(shù) DrawSquare ( ),用邊長做為行數(shù)和每行輸出個數(shù),輸出“*”; (3) 主函數(shù):創(chuàng)建一個邊長為5的正方形;輸出正方形,由鍵盤修改邊長為8;重新輸出正方形。,Object Oriented,for 3:繼承和派生,設(shè)計兩個類,一個類描述點,另一個類描述圓。圓由圓心和半徑構(gòu)成,圓類由點類派生而來,圓心的特性描述由點類繼承下來。要求圓類提供: (1)求圓面積的成員函數(shù) (2) 取圓心坐標(biāo)的兩個函數(shù) Get_X( )和Get_Y( ) (3) 支持初始化的帶參構(gòu)造函數(shù) (4) 主函數(shù),鍵盤輸入圓心坐標(biāo) x,y, 以及半徑 r, 輸出圓面積。,Object Oriented,for 4:繼承和派生,一個圖形是由一個圓和一個矩形構(gòu)成,要求求解圖形的面積。設(shè)計3個類,其中兩個是基類,一個基類描述圓,另一個基類描述矩形,第三個派生類是由一個圓和一個矩形構(gòu)成的圖形類。圓類包含數(shù)據(jù)成員半徑和求圓面積的成員函數(shù),矩形類包含數(shù)據(jù)成員長和寬、求矩形面積的成員函數(shù)。派生的圖形類提供輸出面積的函數(shù)及實現(xiàn)初始化的帶參構(gòu)造函數(shù)。 (圓半徑 r=10, 矩形 長=20, 寬=50,輸出面積),Object Oriented,for 5:虛函數(shù),編一個程序計算正方體,球體和圓柱體的表面積和體積。 要求:抽象出一個公共基類container為抽象類,在其中定義求表面積和體積的純虛函數(shù)。抽象類中定義一個公共的數(shù)據(jù)成員radius,此數(shù)值可以作為球體的半徑、正方體的邊長、圓柱體底面圓半徑。由該抽象類派生出的三個類,都有求表面積和體積的實際定義。鍵盤輸入radius的值后,可以輸出這3種立方體的面積。,Object Oriented,for 6:函數(shù)重載,設(shè)計一個用來表示直角坐標(biāo)系上點的位置的Location類,然后在主程序中創(chuàng)建兩個對象A和 B,要求A在第三象限,B在第二象限,計算給定兩點之間的距離并按如下格式輸出結(jié)果: A(x1,y1),B(x2,y2) Distance=d 其中x1,y1,x2,y2為指定值,d為計算結(jié)果。,Object Oriented,for7 類的應(yīng)用,一圓型游泳池如圖所示,現(xiàn)在需在其周圍建一圓型過道,并在其四周圍上柵欄。柵欄價格為35元/米,過道造價為20元/平方米。過道寬度為3米,游泳池半徑由鍵盤輸入。要求編程計算并輸出過道和柵欄的造價。,Object Oriented,復(fù)習(xí),結(jié)構(gòu)類型用struct定義,是用戶自定義數(shù)據(jù)類型,由不同類型的數(shù)據(jù)成員組成。結(jié)構(gòu)變量在內(nèi)存占有一片連續(xù)的存儲區(qū)間。結(jié)構(gòu)變量成員用圓點運算符和箭頭運算符訪問。 類類型是結(jié)構(gòu)類型的拓展,通常用關(guān)鍵字class定義。類是數(shù)據(jù)成員和成員函數(shù)的封裝。類的實例稱為對象。 數(shù)據(jù)成員是類的屬性,可以為各種合法的C+類型,包括類類型。成員函數(shù)用于操作類的數(shù)據(jù)或在對象之間發(fā)送消息。 類成員由private, protected, public決定訪問特性。public成員集稱為類的接口。不能在類的外部訪問private成員。 構(gòu)造函數(shù)是特殊的成員函數(shù),在創(chuàng)建和初始化對象時自動調(diào)用。析構(gòu)函數(shù)則在對象作用域結(jié)束時自動調(diào)用。,Object Oriented,靜態(tài)成員是局部于類的成員,它提供一種同類對象的共享機制。靜態(tài)數(shù)據(jù)成員在編譯時建立并初始化存儲空間。靜態(tài)數(shù)據(jù)成員和靜態(tài)成員函數(shù)依賴于類而使用,與是否建立對象無關(guān)。 友員是類對象操作的一種輔助手段。一個類的友員可以訪問該類各種性質(zhì)的成員。 從編譯器的觀點看,類是一個程序包。定義什么類成員和如何聲明成員的訪問性質(zhì),取決于問題的需要。,Object Oriented,繼承是面向?qū)ο蟪绦蛟O(shè)計實現(xiàn)軟件重用的重要方法。程序員可以在已有類的基礎(chǔ)上定義新的數(shù)據(jù)成員和成員函數(shù)。原有類稱為基類,新的類稱為派生類,這種程序設(shè)計方法稱為繼承。 派生類成員由基類成員和自身定義的成員組成。單繼承的派生類只有一個基類。多繼承的派生類有多個基類。 對基類成員的訪問性質(zhì)受繼承方式影響。 公有(public)繼承方式,基類的public和protected成員在派生類中性質(zhì)不變; 保護(protected)繼承,基類的public和protected成員都成為派生類的protected成員; 私有(private)繼承,基類的public和protected成員都成為派生類的private成員。,Object Oriented,派生類中不可見基類的私有數(shù)據(jù)成員,但這些數(shù)據(jù)存儲單元依然被建立。創(chuàng)建派生類對象時,派生類的構(gòu)造函數(shù)總是先調(diào)用基類構(gòu)造函數(shù)來初始化派生類中的基類成員。調(diào)用基類構(gòu)造函數(shù)可以通過初始化列表實現(xiàn)數(shù)據(jù)成員的初始化。調(diào)用析構(gòu)函數(shù)的次序和調(diào)用構(gòu)造函數(shù)的次序相反。 類繼承關(guān)系中,覆蓋成員出現(xiàn)訪問的二義性,可以用作用域符顯示指定類成員。 為了避免多繼承類格中的匯點類在派生類對象中產(chǎn)生不同副本,C+提供虛繼承機制。 多繼承提供了軟件重用的強大功能,也增加了程序的復(fù)雜性。,Object Oriented,虛函數(shù)和多態(tài)性使軟件設(shè)計易于擴充。 冠以關(guān)鍵字virtual的成員函數(shù)稱為虛函數(shù)。派生類可以重載基類的虛函數(shù),只要接口相同,函數(shù)的虛特性不變。 基類指針可以指向派生類對象;以及基類中擁有虛函數(shù),是支持多態(tài)性的前提。當(dāng)通過基類指針或引用使用虛函數(shù)時,C+在程序運行時根據(jù)所指對象類型在類層次中正確選擇重定義的函數(shù)。這種運行時的晚期匹配稱為動態(tài)聯(lián)編。 如果通過對象名和點運算符方式調(diào)用虛函數(shù),則調(diào)用關(guān)聯(lián)在編譯時由引用對象的類型確定,稱為靜態(tài)聯(lián)編。 如果一個基類中包含虛函數(shù),通常把它的析構(gòu)函數(shù)說明為虛析構(gòu)函數(shù)。這樣,它的所有派生類析構(gòu)函數(shù)也自動成為虛析構(gòu)函數(shù)(即使它們與基類析構(gòu)函數(shù)名字不相同)。虛析構(gòu)函數(shù)使得用delete算符刪除對象時,系統(tǒng)可以正確地調(diào)用析構(gòu)函數(shù)。,Object Oriented,純虛函數(shù)是在說明時代碼“初始化值”為0的虛函數(shù)。純虛函數(shù)本身沒有實現(xiàn),由它的派生類定義實現(xiàn)版本。 具有純虛函數(shù)的類稱為抽象類。抽象類只能作為基類,不能建立實例化對象。如果抽象類的派生類不提供純虛函數(shù)的實現(xiàn),則它依然是抽象類。定義了純虛函數(shù)實現(xiàn)的派生類,即可以建立對象的類稱為具體類。 盡管不能建立抽象類對象,但抽象類機制提供的軟件抽象和可擴展性的手段;抽象類指針使得派生的具體類對象具有多態(tài)操作能力。異質(zhì)鏈表是多態(tài)應(yīng)用的一個實例。,Object Oriented,運算符重載的作用是令用戶可以像操作基本數(shù)據(jù)類型一樣,用簡潔明確的運算符操作- 1.請仔細(xì)閱讀文檔,確保文檔完整性,對于不預(yù)覽、不比對內(nèi)容而直接下載帶來的問題本站不予受理。
- 2.下載的文檔,不會出現(xiàn)我們的網(wǎng)址水印。
- 3、該文檔所得收入(下載+內(nèi)容+預(yù)覽)歸上傳者、原創(chuàng)作者;如果您是本文檔原作者,請點此認(rèn)領(lǐng)!既往收益都?xì)w您。
下載文檔到電腦,查找使用更方便
14.9 積分
下載 |
- 配套講稿:
如PPT文件的首頁顯示word圖標(biāo),表示該PPT已包含配套word講稿。雙擊word圖標(biāo)可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設(shè)計者僅對作品中獨創(chuàng)性部分享有著作權(quán)。
- 關(guān) 鍵 詞:
- 西安 工業(yè)大學(xué) 耿軍雪 老師 課件 多態(tài)性
鏈接地址:http://italysoccerbets.com/p-2842203.html