版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
C++語(yǔ)言程序設(shè)計(jì)第5章多態(tài)性與虛函數(shù)本章主要內(nèi)容重載靜態(tài)關(guān)聯(lián)與動(dòng)態(tài)關(guān)聯(lián)虛函數(shù)純虛函數(shù)與抽象類虛析構(gòu)函數(shù)
§5.1重載在類中,構(gòu)造函數(shù)可以重載,普通成員函數(shù)也可以重載;構(gòu)造函數(shù)重載給初始化帶來(lái)了多種方式,為用戶提供了更大的靈活性。一、函數(shù)重載二、運(yùn)算符重載的幾個(gè)問(wèn)題1、哪些運(yùn)算符可以重載?算術(shù)運(yùn)算符:+、-、*、/、%、++、--;位操作運(yùn)算符:&、|、~、^、<<、>>;邏輯運(yùn)算符:!、&&、||;比較運(yùn)算符:>、<、>=、<=、==、!=;賦值運(yùn)算符:=、+=、-=、*=、/=、%=、
&=、|=、~=、<<=、>>=;其他運(yùn)算符:[]、()、->、'
、new、delete、
new[]、delete[]、->*;不允許重載的運(yùn)算符:.、*、::、?:、sizeof;2、編譯程序如何選用哪一個(gè)運(yùn)算符函數(shù)?運(yùn)算符實(shí)質(zhì)上是函數(shù),遵循函數(shù)重載原則;3、運(yùn)算符重載時(shí)必須遵循哪些原則?重載運(yùn)算符含義必須清楚;重載運(yùn)算符不能有二義性;4、重載運(yùn)算符有哪些限制?不可臆造新的運(yùn)算符;重載運(yùn)算符堅(jiān)持4個(gè)“不能改變”:不能改變運(yùn)算符操作數(shù)的個(gè)數(shù);不能改變運(yùn)算符原有的優(yōu)先級(jí);不能改變運(yùn)算符原有的結(jié)合性;不能改變運(yùn)算符原有的語(yǔ)法結(jié)構(gòu);函數(shù)類型operator運(yùn)算符名稱(形參表列){對(duì)運(yùn)算符的重載處理}其參數(shù)中至少有一個(gè)為類對(duì)象或類對(duì)象的引用。
三、運(yùn)算符重載函數(shù)一般格式四、運(yùn)算符重載函數(shù)的兩種形式1、重載為類的成員函數(shù)重載一元運(yùn)算符,不再顯式說(shuō)明參數(shù);重載二元運(yùn)算符,只顯式說(shuō)明一個(gè)參數(shù);該參數(shù)為操作數(shù)的右操作數(shù),左操作數(shù)由this指針(指向調(diào)用該成員函數(shù)的對(duì)象)提供;重載為成員函數(shù)時(shí),隱含了一個(gè)參數(shù)(this指針);[例]分析下列程序的輸出結(jié)果。#include<iostream.h>classcomplex{public:
complex(doubler=0,doublei=0);
complexoperator+(constcomplex&c);
complexoperator-(constcomplex&c);
complexoperator-();voidprint()const;private:doublereal,imag;};complex::complex(doubler,doublei){+運(yùn)算符-運(yùn)算符求負(fù)運(yùn)算符
real=r;
imag=i;}complexcomplex::operator+(constcomplex&c){doubler=real+c.real;doublei=imag+c.imag;returncomplex(r,i);}complexcomplex::operator-(constcomplex&c){doubler=real-c.real;doublei=imag-c.imag;returncomplex(r,i);}complexcomplex::operator-(){returncomplex(-real,-imag);}voidcomplex::print()const{
cout<<'('<<real<<','<<imag<<')'<<endl;}voidmain(){complexc1(2.5,3.7),c2(4.2,6.5);complexc;c=c1-c2;c.print();c=c1+c2;c=c1.operator-(c2);c=c1.operator+(c2);
c.print();c=-c1;c.print();}輸出
(-1.7,-2.8)
(6.7,10.2)
(-2.5,-3.7)c=c1.operator-();2、重載為友元函數(shù)重載為友元函數(shù)時(shí),沒(méi)有隱含的參數(shù)this指針,即不改變?cè)羞\(yùn)算符的語(yǔ)法結(jié)構(gòu);重載為友元函數(shù)的運(yùn)算符重載函數(shù)的格式:friend<類型說(shuō)明符>operator<運(yùn)算符>(<參數(shù)表>){……}[例]分析下列程序的輸出結(jié)果。#include<iostream.h>classcomplex{public:
complex(doubler=0,doublei=0);friendcomplexoperator+(constcomplex&c1,constcomplex&c2);
friendcomplex
operator-(constcomplex&c1,constcomplex&c2);
friendcomplexoperator-(constcomplex&c);voidprint()const;private:doublereal,imag;};+運(yùn)算符-運(yùn)算符求負(fù)運(yùn)算符complex::complex(doubler,doublei){real=r;
imag=i;}complexoperator+(constcomplex&c1,constcomplex&c2){doubler=c1.real+c2.real;doublei=c1.imag+c2.imag;returncomplex(r,i);}complexoperator-(constcomplex&c1,constcomplex&c2){
doubler=c1.real-c2.real;doublei=c1.imag-c2.imag;returncomplex(r,i);}complexoperator-(constcomplex&c){returncomplex(-c.real,-c.imag);}voidcomplex::print()const{
cout<<'('<<real<<','<<imag<<')'<<endl;}voidmain(){complexc1(2.5,3.7),c2(4.2,6.5);
complexc;c=c1-c2;c.print();c=c1+c2;c.print();c=-c1;c.print();}輸出
(-1.7,-2.8)
(6.7,10.2)
(-2.5,-3.7)c=operator-(c1,c2);c=operator+(c1,c2);c=operator-(c1);3、兩種重載形式的比較一般情況下,單目運(yùn)算符最好重載為成員函數(shù);雙目運(yùn)算符則最好重載為友元函數(shù);如果重載為成員函數(shù),必須要求運(yùn)算表達(dá)式第一個(gè)參數(shù)是類對(duì)象,且與運(yùn)算符函數(shù)類型相同。如果重載為友員函數(shù),必須有兩個(gè)形參,不能省略。多態(tài)性:發(fā)出同樣的消息被不同類型的對(duì)象接受導(dǎo)致完全不同的行為;多態(tài)可分為:靜態(tài)多態(tài)性與動(dòng)態(tài)多態(tài)性;動(dòng)態(tài)多態(tài)性必須存在于繼承的環(huán)境之中;多態(tài)性的概念概念:靜態(tài)關(guān)聯(lián):在編譯時(shí)進(jìn)行的關(guān)聯(lián),即編譯時(shí)就確定了程序中的操作調(diào)用與執(zhí)行該操作代碼之間的關(guān)系。關(guān)聯(lián):確定調(diào)用具體對(duì)象的過(guò)程。(把一個(gè)標(biāo)識(shí)符和一個(gè)地址聯(lián)系起來(lái))§5.2靜態(tài)關(guān)聯(lián)和動(dòng)態(tài)關(guān)聯(lián)動(dòng)態(tài)關(guān)聯(lián):在程序執(zhí)行時(shí)進(jìn)行的關(guān)聯(lián);實(shí)現(xiàn):C++動(dòng)態(tài)關(guān)聯(lián)在虛函數(shù)的支持下實(shí)現(xiàn);§5.3虛函數(shù)1、虛函數(shù)虛函數(shù)是動(dòng)態(tài)關(guān)聯(lián)的基礎(chǔ);virtual<類型說(shuō)明符><函數(shù)名>(<參數(shù)表>)說(shuō)明方法:含義:若類中一成員函數(shù)被說(shuō)明為虛函數(shù),則該成員函數(shù)在派生類中可能有不同的實(shí)現(xiàn)。當(dāng)使用該成員函數(shù)操作指針或引用所標(biāo)識(shí)的對(duì)象時(shí),對(duì)該成員函數(shù)調(diào)用可采用動(dòng)態(tài)關(guān)聯(lián)方式。[例]分析下列程序的輸出結(jié)果。#include<iostream.h>classPoint{public:Point(doublei,doublej){x=i;y=j;}
virtualdoubleArea()const{return0;}private:doublex,y;};classRectangle:public
Point{public:
Rectangle(int
i,int
j,int
k,intl);
virtualdoubleArea()const{returnw*h;}private:虛函數(shù)虛函數(shù)
doublew,h;};Rectangle::Rectangle(int
i,int
j,int
k,intl):Point(i,j){w=k;h=l;}voidfun(Point&s){
cout<<s.Area()<<endl;}voidmain(){
Rectanglerect(3.0,5.2,15.0,25.0);
fun(rect);}輸出:
375[例]分析下列程序的輸出結(jié)果,并回答問(wèn)題。#include<iostream.h>classA{public:
virtual
voidact1()
{cout<<"A::act1()called."<<endl;}voidact2(){act1();}};classB:publicA{public:
voidact1(){cout<<"B::act1()called."<<endl;}};公有繼承,B是A的子類型虛函數(shù)voidmain(){Bb;b.act2();}回答下列問(wèn)題:(1)、該程序執(zhí)行后的輸出結(jié)果是什么?為什么?輸出結(jié)果為:B::act1()called.原因:a.B從A公有繼承,B是A的子類型;
b.B中的act1()為虛函數(shù);
c.b.act2()調(diào)用A中的act2(),進(jìn)一步調(diào)用act1(),產(chǎn)生動(dòng)態(tài)關(guān)聯(lián),運(yùn)行時(shí)選擇B::act1();為什么?(2)、如果將A::act2()的實(shí)現(xiàn)改為:
voidA::act2()
{
this->act1();
}
輸出結(jié)果是什么?為什么?輸出結(jié)果與(1)相同,即:B::act1()called.原因:this指向操作該成員函數(shù)的對(duì)象,基于與(1)相同的原因,此處調(diào)用B::act1()。(3)、如果將A::act2()的實(shí)現(xiàn)改為:
voidA::act2()
{
A::act1();
}
輸出結(jié)果是什么?為什么?輸出結(jié)果:A::act1()called.原因:此處增加了成員名限定,因此要進(jìn)行靜態(tài)關(guān)聯(lián),即調(diào)用的是A::act1()。派生類中對(duì)基類的虛函數(shù)進(jìn)行替換時(shí),要求派生類中說(shuō)明的虛函數(shù)與基類中的被替換的虛函數(shù)之間滿足下列條件:參數(shù)個(gè)數(shù):與基類的虛函數(shù)有相同的參數(shù)個(gè)數(shù);參數(shù)類型:與基類的虛函數(shù)的對(duì)應(yīng)參數(shù)類型相同;返回值類型:與基類的虛函數(shù)的返回值類型相同;滿足上述條件的派生類虛函數(shù),可不加virtual說(shuō)明?!?.4純虛函數(shù)1、引入在基類中不能為虛函數(shù)給出一個(gè)有意義的實(shí)現(xiàn)時(shí),可將其聲明為純虛函數(shù),其實(shí)現(xiàn)留待派生類完成;2、作用為派生類提供一個(gè)一致的接口;3、聲明格式
class<類名>
{
virtual<類型><函數(shù)名>(<參數(shù)表>)=0;
……
}[例]分析下列程序的輸出結(jié)果。#include<iostream.h>classPoint{public:
Point(inti=0,intj=0){x0=i;y0=j;}
virtual
voidSet()=0;virtualvoidDraw()=0;protected:
intx0,y0;};classLine:publicPoint{public:
Line(inti=0,intj=0,intm=0,intn=0):Point(i,j){x1=m;y1=n;}voidSet(){cout<<"Line::Set()called."<<endl;}voidDraw(){cout<<"Line::Draw()called."<<endl;}protected:
intx1,y1;};classEllipse:publicPoint{public:
Ellipse(inti=0,intj=0,intp=0,intq=0):Point(i,j){x2=p;y2=q;}
voidSet(){cout<<"Ellipse::Set()called."<<endl;}
voidDraw(){cout<<"Ellipse::Draw()called."<<endl;}protected:
intx2,y2;};voidDrawObj(Point*p){p->Draw();}voidSetObj(Point*p){p->Set();}voidmain(){Line*lineobj=newLine;Ellipse*ellipseobj=newEllipse;
DrawObj(lineobj);
DrawObj(ellipseobj);
cout<<endl;
SetObj(lineobj);
SetObj(ellipseobj);
cout<<endl<<"Redrawtheobject…"<<endl;
DrawObj(lineobj);
DrawObj(ellipseobj);}
Line::Draw()called.
Ellipse::Draw()called.
Line::Set()called.
Ellipse::Set()called.
Redrawtheobject...
Line::Draw()called.
Ellipse::Draw()called.執(zhí)行結(jié)果§5.5抽象類帶有純虛函數(shù)的類稱為抽象類;抽象類只能作為基類使用,其純虛函數(shù)的實(shí)現(xiàn)由派生類給出;但派生類仍可不給出純虛函數(shù)的定義,繼續(xù)作為抽象類存在;抽象類不能定義對(duì)象,一般將該類的構(gòu)造函數(shù)說(shuō)明為保護(hù)的訪問(wèn)控制權(quán)限;抽象類的作用:用作基類:在一個(gè)繼承層次結(jié)構(gòu)中,提供一個(gè)公共的根,并基于抽象類的操作設(shè)計(jì)出對(duì)抽象類所描述的一類對(duì)象進(jìn)行操作的公共接口,其完整的實(shí)現(xiàn)由派生類完成;用作指針或引用的基類型:保證進(jìn)入繼承層次的每個(gè)類都具有(提供)純虛函數(shù)所要求的行為;在成員函數(shù)內(nèi)可以調(diào)用純虛函數(shù),但在構(gòu)造函數(shù)或析構(gòu)函數(shù)內(nèi)不能調(diào)用純虛函數(shù)(純虛函數(shù)沒(méi)有實(shí)現(xiàn)代碼);
classA
{
public:
virtual
voidf()=0;
voidg(){f();}
A(){f();}
}正確錯(cuò)誤§5.6虛析構(gòu)函數(shù)虛析構(gòu)函數(shù)
在析構(gòu)函數(shù)前加關(guān)鍵字virtual進(jìn)行說(shuō)明,則該析構(gòu)函數(shù)稱為虛析構(gòu)函數(shù);格式:
classB
{
public:
virtual
~B();
…...
}如果一個(gè)類的析構(gòu)函數(shù)被說(shuō)明為虛析構(gòu)函數(shù),則它的派生類中的析構(gòu)函數(shù)也是虛析構(gòu)函數(shù),不管它是否使用了關(guān)鍵字vi
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 吉林藝術(shù)學(xué)院《水彩畫(huà)實(shí)踐》2021-2022學(xué)年第一學(xué)期期末試卷
- 2024年供應(yīng)工廠燈具合同范本
- 吉林師范大學(xué)《中國(guó)現(xiàn)當(dāng)代文學(xué)》2021-2022學(xué)年第一學(xué)期期末試卷
- 2024年大型游艇租賃合同范本
- 2024年大批旺鋪轉(zhuǎn)讓合同范本
- 2022年公務(wù)員多省聯(lián)考《申論》真題(河南縣級(jí)卷)及答案解析
- 燒烤店商家合作協(xié)議書(shū)范文
- 外研版高中英語(yǔ)選修6教案
- (人教版2024)數(shù)學(xué)四年級(jí)上冊(cè)第7單元《條形統(tǒng)計(jì)圖》大單元教學(xué)課件
- 吉林師范大學(xué)《世界古代史專題》2021-2022學(xué)年第一學(xué)期期末試卷
- 動(dòng)畫(huà)概論教程課件 第4章 動(dòng)畫(huà)的分類
- 區(qū)域市場(chǎng)的開(kāi)發(fā)與管理
- 單元103熱固性塑料注射成型及模具
- 譯林版六年級(jí)上冊(cè)英語(yǔ) unit 5 story time課件
- 五年級(jí)上冊(cè)閱讀理解20篇(附帶答案解析)經(jīng)典1
- 2023年國(guó)家電投校園招聘筆試題庫(kù)及答案解析
- SB/T 10016-2008冷凍飲品冰棍
- GB/T 28035-2011軟件系統(tǒng)驗(yàn)收規(guī)范
- GB/T 1591-2008低合金高強(qiáng)度結(jié)構(gòu)鋼
- 公開(kāi)課課件拿來(lái)主義
- 煤礦人力資源管理制度
評(píng)論
0/150
提交評(píng)論