版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第9章多態(tài)性和虛函數(shù)9.1多態(tài)性的概念多態(tài)性是指不同類的對(duì)象對(duì)于同一消息的處理具有不同的實(shí)現(xiàn)。多態(tài)性在C++中表現(xiàn)為同一形式的函數(shù)調(diào)用,可能調(diào)用不同的函數(shù)實(shí)現(xiàn)。從系統(tǒng)實(shí)現(xiàn)的角度看,C++的多態(tài)性分為兩類,一類稱為編譯時(shí)刻多態(tài)性,另一類稱為運(yùn)行時(shí)刻多態(tài)性,也稱動(dòng)態(tài)多態(tài)性。9.1.1編譯時(shí)刻的多態(tài)性C++編譯時(shí)多態(tài)性通過重載(函數(shù)重載和運(yùn)算符重載)來實(shí)現(xiàn)【例9.1】編譯時(shí)刻的多態(tài)性——運(yùn)算符重載:下面這段程序建立Rectangle類和Cuboid類,并重載運(yùn)算符“+=”,使之能用于相應(yīng)類對(duì)象的運(yùn)算。#include<iostream>usingnamespacestd;classRectangle//定義矩形類{public:
Rectangle(doublew=0,doublel=0); //缺省構(gòu)造函數(shù)
voidset_wl(double
w,doublel);doubleget_w()const;doubleget_l()const;doublearea();~Rectangle(){}; //析構(gòu)函數(shù)
Rectangle&operator+=(Rectangle&rec_add) //重載運(yùn)算符+={width+=rec_add.width;length+=rec_add.length;return*this; //返回當(dāng)前對(duì)象
}protected:
intwidth;
intlength;};Rectangle::Rectangle(doublew,doublel):width(w),length(l){}voidRectangle::set_wl(double
w,doublel){width=w;length=l;}doubleRectangle::get_w()const{returnwidth;}doubleRectangle::get_l()const{returnlength;}doubleRectangle::area(){returnwidth*length;}classCuboid:publicRectangle//定義長(zhǎng)方體類{public:
Cuboid(doublew=0,doublel=0,doubleh=0);voidset_wlh(double
w,double
l,doubleh);doubleget_h()const;doublearea();
Cuboid&operator+=(Cuboid&cub_add){width+=cub_add.width;length+=cub_add.length;height+=cub_add.height;return*this; //返回當(dāng)前對(duì)象
}protected:doubleheight;};Cuboid::Cuboid(double
w,double
l,double
h):Rectangle(w,l),height(h){}voidCuboid::set_wlh(double
w,double
l,doubleh){width=w;length=l;height=h;}doubleCuboid::get_h()const{returnheight;}doubleCuboid::area(){return2*(width*length+width*height+length*height);}//求長(zhǎng)方體的表面積intmain(){Rectanglerec1(1,2);Rectanglerec2;
Cuboidcub1(1,2,3);
Cuboidcub2;rec2.set_wl(2,4);cub2.set_wlh(5,10,15);
cout<<"rec1:(width="<<rec1.get_w()<<",length="<<rec1.get_l()<<")"<<endl;
cout<<"rec2:(width="<<rec2.get_w()<<",length="<<rec2.get_l()<<")"<<endl;
rec2+=rec1; //調(diào)用Rectangle類的重載運(yùn)算符:+=
cout<<"rec2.width=("<<rec2.get_w()<<",length="<<rec2.get_l()<<")"<<endl;
cout<<"cub1:(width="<<cub1.get_w()<<",length="<<cub1.get_l()<<",height=";
cout<<cub1.get_h()<<")"<<endl;
cout<<"cub2:(width="<<cub2.get_w()<<",length="<<cub2.get_l()<<",height=";
cout<<cub2.get_h()<<")"<<endl;cub2+=cub1; //調(diào)用Cuboid類的重載運(yùn)算符:+=
cout<<"cub2:(width="<<cub2.get_w()<<",length="<<cub2.get_l()<<",height=";
cout<<cub2.get_h()<<")"<<endl;
cout<<"rec2'sareais"<<rec2.area()<<endl;
cout<<"cub2'sareais"<<cub2.area()<<endl;return0;}9.1.2運(yùn)行時(shí)刻的多態(tài)性
運(yùn)行時(shí)刻多態(tài)性的實(shí)現(xiàn)是指在程序運(yùn)行過程中根據(jù)具體情況來確定調(diào)用的是哪一個(gè)函數(shù),它是通過動(dòng)態(tài)聯(lián)編機(jī)制實(shí)現(xiàn)的【例9.2】運(yùn)行時(shí)刻的多態(tài)性運(yùn)行時(shí)的多態(tài)性。仍然用例9.1中定義的Rectangle類和Cuboid類。//*************ex9_2.cpp*************//此處加上例9.1中定義的Rectangle類和Cuboid類。intmain(){Rectangle*r;
Cuboidcub3(1,2,3);
cout<<"cub3=("<<cub3.get_w()<<","<<cub3.get_l()<<",";
cout<<cub3.get_h()<<")"<<endl;r=&cub3; //用基類指針指向派生類對(duì)象
cout<<"cub3'sareais(*r)"<<r->area()<<endl;
cout<<"cub3'sareais(cub3)"<<cub3.area()<<endl;return0;}程序的運(yùn)行結(jié)果如下:cub3=(1,2,3)cub3'sareais(*r)2cub3'sareais(cub3)22運(yùn)行時(shí)刻的多態(tài)性是面向?qū)ο蟮囊粋€(gè)非常重要的特征,再來看一個(gè)在結(jié)構(gòu)化編程中的例子:【例9.3】下面這段程序是利用多分支結(jié)構(gòu)編程模擬實(shí)現(xiàn)繪制圖形的函數(shù)。//********ex9_3.cpp*********voiddraw(int
obj_figure){switch(obj_figure)
case0://rectangle
draw_rectangle();
//cout<<”drawrectangle”<<endl;
break;
case1://triangle
draw_triangle();
//cout<<”drawtriangle”<<endl;
break;
case2://circle
draw_circle();
//cout<<"draw_circle"<<endl;
break;}這種編程方式使得程序的可維護(hù)性和可擴(kuò)充性都變得很差。那么有沒有更好的方法實(shí)現(xiàn)上述例子?看看下面的程序段:voiddraw(void*f){
(*f)();}9.2虛函數(shù)虛函數(shù)的作用 虛函數(shù)從表現(xiàn)形式看是指那些被virtual關(guān)鍵字修飾的成員函數(shù)。類的一個(gè)成員函數(shù)如果被說明為虛函數(shù),表明它目前的具體實(shí)現(xiàn)僅是一種適用于當(dāng)前類的實(shí)現(xiàn),而在該類的繼承層次鏈條中有可能重新定義這個(gè)成員函數(shù)的實(shí)現(xiàn),即這個(gè)虛函數(shù)可能會(huì)被派生類的同名函數(shù)所覆蓋(override)。例:使用虛函數(shù)的例子#include<iostream>usingstd::cout;usingstd::endl;classfigure{public:virtualvoiddraw()//將draw()定義為虛函數(shù){cout<<"drawfigure"<<endl;}};classrectangle:publicfigure{voiddraw(){
cout<<"drawrectangle"<<endl;}};classtriangle:publicfigure{voiddraw(){
cout<<"drawtriangle"<<endl;}};intmain(){figure*f;rectangler1;trianglet1;f=&r1;//基類指針f指向派生類對(duì)象r1f->draw();//調(diào)用r1的成員函數(shù)draw()f=&t1;//基類指針f指向派生類對(duì)象t1f->draw();//調(diào)用t1的成員函數(shù)draw()return0;}程序運(yùn)行結(jié)果:虛函數(shù)的使用虛函數(shù)的實(shí)現(xiàn)機(jī)制和調(diào)用方式與非虛函數(shù)不同,虛函數(shù)的使用需要注意以下幾點(diǎn):1.虛函數(shù)的聲明 只能將類的成員函數(shù)聲明為虛函數(shù),而不能將類外的普通函數(shù)聲明為虛函數(shù)。虛函數(shù)的作用是允許在派生類中對(duì)基類的虛函數(shù)重新定義,因而它只能用于類的繼承層次結(jié)構(gòu)中。2.虛函數(shù)的訪問權(quán)限 派生類中虛函數(shù)的訪問權(quán)限并不影響虛函數(shù)的動(dòng)態(tài)聯(lián)編,如下面的例9.5,其中派生類CDerived中重新定義了虛函數(shù)F4(),在程序的運(yùn)行中由于虛函數(shù)的機(jī)制,在CBase::F3()中調(diào)用F4()時(shí)會(huì)調(diào)用CDerived::F4(),而該函數(shù)的訪問權(quán)限是私有的。3.成員函數(shù)中調(diào)用虛函數(shù) 在類的成員函數(shù)中可以直接調(diào)用相應(yīng)類中定義或重新定義的虛函數(shù),分析這類函數(shù)的調(diào)用次序時(shí)要注意成員函數(shù)的調(diào)用一般是隱式調(diào)用,應(yīng)該將其看成是通過this指針的顯式調(diào)用?!纠?.5】在成員函數(shù)中調(diào)用虛函數(shù)//*********ex9_5.cpp***********#include<iostream>usingnamespacestd;classCBase{public:voidF1(){
cout<<"=>CBase-F1=>";F2();}voidF2(){
cout<<"CBase-F2=>";F3();}virtualvoidF3(){
cout<<"CBase-F3=>";F4();//即this->F4()}virtualvoidF4(){
cout<<"CBase-F4=>";}};classCDerived:public
CBase{private:virtualvoidF4(){
cout<<"Derived-F4=>out"<<endl;}public:voidF1(){
cout<<"=>Derived-F1=>";CBase::F2();}voidF2(){
cout<<"=>Derived-F2=>";F3();//即this->F3()}};intmain(){
CBase*pB;
CDerived
Obj;程序運(yùn)行結(jié)果:
pB=&Obj;
pB->F1();Obj.F1();return0;}9.3純虛函數(shù)與抽象類純虛函數(shù)在程序設(shè)計(jì)中,通常會(huì)在類層次的頂層以虛函數(shù)的形式給出該類層次所提供的某些操作的統(tǒng)一接口,由于層次較高,有些操作無法(也無必要)給出具體的實(shí)現(xiàn),對(duì)于這種情況可以不對(duì)虛函數(shù)的實(shí)現(xiàn)進(jìn)行定義,而將它們說明為純虛函數(shù)。純虛函數(shù)是在聲明虛函數(shù)時(shí)被“初始化”為0的函數(shù)。聲明純虛函數(shù)的一般形式是:virtual<函數(shù)類型><函數(shù)名>(參數(shù)表列)=0;抽象類具有純虛函數(shù)的類無法用于創(chuàng)建對(duì)象,因?yàn)樗募兲摵瘮?shù)無函數(shù)體,所以又把這種含有純虛函數(shù)的類稱為抽象類。抽象類的主要作用是為一個(gè)族類提供統(tǒng)一的公共接口,用戶在這個(gè)基礎(chǔ)上根據(jù)自己的需要定義出功能各異的派生類,以有效地發(fā)揮多態(tài)的特性。使用抽象類時(shí)應(yīng)注意以下問題:⑴抽象類只能用作其它類的基類,不能建立抽象類的對(duì)象。因?yàn)樗募兲摵瘮?shù)沒有定義功能。⑵抽象類不能用作參數(shù)類型、函數(shù)的返回類型或顯式轉(zhuǎn)換的類型。⑶可以聲明抽象類的指針和引用,通過它們,可以指向并訪問派生類對(duì)象,從而訪問派生類的成員。⑷如果在抽象類所派生出的新類中對(duì)基類的所有純虛函數(shù)進(jìn)行了定義,那么這些函數(shù)就被賦予了功能,可以被調(diào)用。這個(gè)派生類就不是抽象類,而是可以用來定義對(duì)象的具體類。如果在派生類中沒有對(duì)所有純虛函數(shù)進(jìn)行定義,則此派生類仍然是抽象類,不能用來定義對(duì)象。9.4抽象類的實(shí)例一個(gè)抽象類就是一個(gè)界面。類層次結(jié)構(gòu)是一種逐步遞增地建立類的方式。有些抽象類也提供了重要的功能,支持進(jìn)一步向上構(gòu)造。類層次結(jié)構(gòu)中的各個(gè)類一方面為用戶提供了有用的功能,同時(shí)也作為實(shí)現(xiàn)更高級(jí)或者更特殊的類的構(gòu)造塊。這種層次結(jié)構(gòu)對(duì)于支持以逐步求精方式進(jìn)行的程序設(shè)計(jì)是非常理想的?!纠?.10】抽象類實(shí)例#include<iostream>usingnamespacestd;classCShape{//定義為一個(gè)抽象類,即一個(gè)圖形界面接口public:virtualdoublearea()const{return0.0;}//定義為虛函數(shù),允許后面覆蓋
virtualvoidprintShapeName()const=0;//定義為純虛函數(shù),由派生類負(fù)責(zé)實(shí)現(xiàn)
virtualvoiddraw()const=0;//定義為純虛函數(shù)};classCPoint:public
CShape//公有繼承CShape{public:
CPoint(int=0,int=0);//聲明構(gòu)造函數(shù)
voidsetPoint(int,int);
int
getX()const{returnx;}
int
getY()const{returny;}virtualvoidprintShapeName()const//覆蓋CShape基類的純虛函數(shù)
{cout<<"Point:";}virtualvoiddraw()const;private:
int
x,y;};CPoint::CPoint(int
a,intb)//CPoint構(gòu)造函數(shù)的實(shí)現(xiàn){setPoint(a,b);}voidCPoint::setPoint(int
a,intb){x=a;y=b;}voidCPoint::draw()const{cout<<"["<<x<<","<<y<<"]";}classCCircle:public
CPoint{public:
CCircle(doubler=0.0,intx=0,inty=0);voidsetRadius(double);doublegetRadius()const;virtualdoublearea()const;virtualvoidprintShapeName()const{cout<<"Circle:";}virtualvoiddraw()const;private:doubleradius;};CCircle::CCircle(double
r,int
a,int
b):CPoint(a,b){setRadius(r);}voidCCircle::setRadius(doubler){radius=r>0?r:0;}doubleCCircle::getRadius()const{returnradius;}doubleCCircle::area()const{return3.1415926*radius*radius;}voidCCircle::draw()const{
CPoint::draw();
cout<<";Radius="<<radius;}classCRectangle:public
CPoint{public:
CRectangle(doublewidth=0.0,doubleheight=0.0,intx=0,inty=0);voidsetWidth(double);doublegetWidth();voidsetHeight(double);doublegetHeight();virtualdoublearea()const;virtualvoidprintShapeName()const{cout<<"Rectangle:";}virtualvoiddraw()const;private:doublewidth;doubleheight;};CRectangle::CRectangle(double
w,double
h,intx,inty):CPoint(x,y){setWidth(w);
setHeight(h);}voidCRectangle::setWidth(doublew){width=w>0?w:0;}voidCRectangle::setHeight(doubleh){height=h>0?h:0;}doubleCRectangle::getWidth(){returnwidth;}doubleCRectangle::getHeight(){returnheight;}doubleCRectangle::area()const{returnwidth*height;}voidCRectangle::draw()const{CPoint::draw();
cout<<"width="<<width<<";Height="<<height;}voidViaPointer(const
CShape*);voidViaReference(const
CShape&);intmain(){
CPointpoint(5,9);//定義point對(duì)象并初始化
CCirclecircle(4.5,14,8);//定義circle對(duì)象并初始化
CRectanglerectangle(12,3.5,8,9);//定義rectangle對(duì)象并初始化
point.printShapeName();//靜態(tài)綁定
point.draw();//靜態(tài)綁定
cout<<endl;
circle.printShapeName();//靜態(tài)綁定
circle.draw();//靜態(tài)綁定
cout<<endl;
rectangle.printShapeName(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2023勞動(dòng)者就業(yè)協(xié)議書內(nèi)容七篇
- 2023雙方保密協(xié)議書七篇
- 協(xié)議書范本汽車
- 2023房子裝修雙方協(xié)議書七篇
- 新疆維吾爾自治區(qū)喀什地區(qū)疏勒縣實(shí)驗(yàn)學(xué)校教育集團(tuán)2023-2024學(xué)年七年級(jí)11月月考道德與法治試題(原卷版)-A4
- 2024秋新滬科版物理8年級(jí)上冊(cè)教學(xué)課件 第6章 熟悉而陌生的力 第3節(jié) 來自地球的力
- 2023年藥品包裝機(jī)械項(xiàng)目融資計(jì)劃書
- 2023年聚氨酯涂料項(xiàng)目融資計(jì)劃書
- 烹飪?cè)现R(shí)習(xí)題+參考答案
- 黑龍江省佳木斯市富錦市2024屆九年級(jí)上學(xué)期期末考試數(shù)學(xué)試卷(含答案)
- 《Stata統(tǒng)計(jì)分析與應(yīng)用》課程教學(xué)大綱
- 09阜新地價(jià)修正體系
- 華海醫(yī)藥智慧園區(qū)方案
- 中小學(xué)教師信息技術(shù)應(yīng)用能力發(fā)展測(cè)評(píng):30項(xiàng)微能力
- 旅游地理學(xué)發(fā)展簡(jiǎn)史
- 常見鵝病診斷和防治
- 鉆孔灌注樁施工危險(xiǎn)源識(shí)別及防控措施
- 藍(lán)色企業(yè)發(fā)展歷程時(shí)間軸PPT模板課件
- 新《行政處罰法》修訂對(duì)比解讀PPT課件
- 水電站課程設(shè)計(jì) 40
- 酒精發(fā)酵相關(guān)化驗(yàn)指標(biāo)測(cè)定
評(píng)論
0/150
提交評(píng)論