C++面向?qū)ο蟪绦蛟O(shè)計_第1頁
C++面向?qū)ο蟪绦蛟O(shè)計_第2頁
C++面向?qū)ο蟪绦蛟O(shè)計_第3頁
C++面向?qū)ο蟪绦蛟O(shè)計_第4頁
C++面向?qū)ο蟪绦蛟O(shè)計_第5頁
已閱讀5頁,還剩99頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

VisualC++面向?qū)ο缶幊陶Z言第三章C++面向?qū)ο蟪绦蛟O(shè)計第三章C++面向?qū)ο蟪绦蛟O(shè)計3.1面向?qū)ο蟪绦蛟O(shè)計概述3.1.1傳統(tǒng)的結(jié)構(gòu)化程序設(shè)計3.1.2面向?qū)ο蟪绦蛟O(shè)計方法及特征3.2C++類3.2.1類的定義與實現(xiàn)3.2.2構(gòu)造函數(shù)和析構(gòu)函數(shù)3.2.3this指針3.2.4靜態(tài)成員3.2.5友元3.3類的繼承3.3.1基類和派生類3.3.2基類和派生類的構(gòu)造函數(shù)3.3.3多重繼承3.3.4虛基類3.4多態(tài)性和虛函數(shù)3.4.1用基類指針指向派生類對象3.4.2虛函數(shù)3.4.3抽象類和純虛函數(shù)3.5重載3.5.1函數(shù)重載3.5.2運算符重載3.6C++模板3.6.1函數(shù)模板3.6.2類模板3.7MicrosoftVisualC++的語法擴充3.7.1VisualC++自定義數(shù)據(jù)類型3.7.2VisualC++運行庫3.7.3運行時類型識別3.7.4編程規(guī)范結(jié)構(gòu)化程序設(shè)計:將系統(tǒng)分解為若干模塊(即函數(shù));缺點:維護困難,特別是數(shù)據(jù)結(jié)構(gòu)的修改;3.1.1傳統(tǒng)的結(jié)構(gòu)化程序設(shè)計3.1.2面向?qū)ο蟪绦蛟O(shè)計方法及特征對象=數(shù)據(jù)+作用于這些數(shù)據(jù)上的操作;類是具有相同數(shù)據(jù)結(jié)構(gòu)和相同操作功能的對象的集合,對象是類的實例;對象與類的關(guān)系類似于鞋和生產(chǎn)鞋的模具;面向?qū)ο蟪绦蛟O(shè)計把一個復(fù)雜的問題分解為多個能完成獨立功能的對象,分開獨立設(shè)計,再將其整合完成復(fù)雜問題;其理想目標(biāo)是希望編寫程序就像搭積木;面向過程和面向?qū)ο蟮膮^(qū)別面向過程就是分析出解決問題所需要的步驟,然后用函數(shù)把這些步驟一步一步實現(xiàn),使用的時候一個一個依次調(diào)用就可以了。面向?qū)ο笫前褬?gòu)成問題事務(wù)分解成各個對象,建立對象的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為。例如五子棋棋,面向過過程的設(shè)計計思路就是是首先分析析問題的步步驟:1、開始游游戲,2、、黑子先走走,3、繪繪制畫面,,4、判斷斷輸贏,5、輪到白白子,6、、繪制畫面面,7、判判斷輸贏,,8、返回回步驟2,,9、輸出出最后結(jié)果果。把上面每個個步驟用分分別的函數(shù)數(shù)來實現(xiàn),,問題就解解決了。而面向?qū)ο笙蟮脑O(shè)計則則是從另外外的思路來來解決問題題。整個五五子棋可以以分為:1、黑白雙雙方,這兩兩方的行為為是一模一一樣的,2、棋盤系系統(tǒng),負(fù)責(zé)責(zé)繪制畫面面,3、規(guī)規(guī)則系統(tǒng),,負(fù)責(zé)判定定諸如犯規(guī)規(guī)、輸贏等等。第一類對象象(玩家對對象)負(fù)責(zé)責(zé)接受用戶戶輸入,并并告知第二二類對象((棋盤對象象)棋子布布局的變化化,棋盤對對象接收到到了棋子的的變化就要要負(fù)責(zé)在屏屏幕上面顯顯示出這種種變化,同同時利用第第三類對象象(規(guī)則系系統(tǒng))來對對棋局進行行判定。可以明顯地地看出,面面向?qū)ο笫鞘且怨δ軄韥韯澐謫栴}題,而不是是步驟。同樣是繪制制棋局,這這樣的行為為在面向過過程的設(shè)計計中分散在在了總多步步驟中,很很可能出現(xiàn)現(xiàn)不同的繪繪制版本,,因為通常常設(shè)計人員員會考慮到到實際情況況進行各種種各樣的簡簡化。而面面向?qū)ο蟮牡脑O(shè)計中,,繪圖只可可能在棋盤盤對象中出出現(xiàn),從而而保證了繪繪圖的統(tǒng)一一。功能上的統(tǒng)統(tǒng)一保證了了面向?qū)ο笙笤O(shè)計的可可擴展性。。比如我要加加入悔棋的的功能,如如果要改動動面向過程程的設(shè)計,,那么從輸輸入到判斷斷到顯示這這一連串的的步驟都要要改動,甚甚至步驟之之間的循序序都要進行行大規(guī)模調(diào)調(diào)整。如果是面向向?qū)ο蟮脑捲挘挥酶母膭悠灞P對對象就行了了,棋盤系系統(tǒng)保存了了黑白雙方方的棋譜,,簡單回溯溯就可以了了,而顯示示和規(guī)則判判斷則不用用顧及,同同時整個對對對象功能能的調(diào)用順順序都沒有有變化,改改動只是局局部的。在類的定義義中,數(shù)據(jù)據(jù)稱為成員員變量,函函數(shù)稱為方方法;成員變量按按訪問控制制權(quán)限分為為公有和私私有;定義的格式式:

class<類名>

{private:<私有有數(shù)據(jù)成員員和成員函函數(shù)的聲明明>public:<私有數(shù)據(jù)據(jù)成員和成成員函數(shù)的的聲明>protected:<保護數(shù)數(shù)據(jù)成員和和成員函數(shù)數(shù)的聲明>

}3.2.1類的定定義與實現(xiàn)現(xiàn)private屬性性的成員只只允許被本本類的成員員函數(shù)訪問問和調(diào)用;;protected屬性的成成員允許被被本類的成成員函數(shù)和和派生類的的成員函數(shù)數(shù)訪問和調(diào)調(diào)用;例:Time類的定定義

classTime

{private:inthour;intminute;intsecond;public:voidsetTime(int,int,int);voidshowTime();}為什么需要要這兩個函函數(shù)????對于成員函函數(shù)來講,,成員變量量就像全局局變量;類的定義和和一般函數(shù)數(shù)定義類似似,但必須須在成員函函數(shù)名前加加類名和作作用域限定定符(::)Time類類的實現(xiàn)((定義)voidTime::setTime(inth,intm,ints)

{hour=(h>=0&&h<24)?h:0;minute=(m>=0&&m<60)?m:0;second=(s>=0&&s<60)?s:0;}

voidTime::showTime(){

cout<<hour<<‘:’’<<minute<<‘:’<<second<<endl;

}對象的聲明明:就像變變量的聲明明(用模具具生產(chǎn)一個個產(chǎn)品);;格式:<類類名><對象名>;例:Timet1,today;Time*pt1=&t1;比較inti;成員函數(shù)的的調(diào)用:t1.setTime(1,2,3);today.showTime();

pt1->setTime(1,2,3);思考:t1.hour=10;在面向?qū)ο笙蟪绦蛟O(shè)計計中,程序序設(shè)計范型型變成了::確定你需需要哪些類類型,為每每個類型提提供完整的的一組操作作。思考:如果果對于Time類,,在未調(diào)用用setTime前前調(diào)用showTime會怎怎樣?我們需要對對成員變量量初始化;;構(gòu)造造函函數(shù)數(shù)是是一一種種特特殊殊的的成成員員函函數(shù)數(shù),,函函數(shù)數(shù)名名和和類類名名相相同同,,提提供供了了對對成成員員變變量量初初始始化化的的方方法法,,使使得得聲聲明明對對象象時時自自動動初初始始化化對對象象,當(dāng)當(dāng)聲聲明明對對象象時時,,自自動動調(diào)調(diào)用用構(gòu)構(gòu)造造函函數(shù)數(shù);;析構(gòu)構(gòu)函函數(shù)數(shù)也也是是成成員員函函數(shù)數(shù),,用用來來在在系系統(tǒng)統(tǒng)釋釋放放對對象象前前做做一一些些清清理理工工作作,當(dāng)當(dāng)對對象象注注銷銷時時,,自自動動調(diào)調(diào)用用析析構(gòu)構(gòu)函函數(shù)數(shù);;構(gòu)構(gòu)造造函函數(shù)數(shù)和和析析構(gòu)構(gòu)函函數(shù)數(shù)構(gòu)造造函函數(shù)數(shù)的的名名稱稱與與類類名名相相同同,,而而析析構(gòu)構(gòu)函函數(shù)數(shù)必必須須在在類類名名前前加加““~””,,都都沒沒有有返返回回值值;;構(gòu)造造函函數(shù)數(shù)可可以以有有參參數(shù)數(shù),,析析構(gòu)構(gòu)函函數(shù)數(shù)沒沒有有參參數(shù)數(shù);;系統(tǒng)統(tǒng)有有默默認(rèn)認(rèn)的的構(gòu)構(gòu)造造函函數(shù)數(shù)和和析析構(gòu)構(gòu)函函數(shù)數(shù);;可以以有有多多個個構(gòu)構(gòu)造造函函數(shù)數(shù)((參參數(shù)數(shù)類類型型不不同同)),,使使得得創(chuàng)創(chuàng)建建的的對對象象根根據(jù)據(jù)數(shù)數(shù)據(jù)據(jù)類類型型的的不不同同((整整型型和和實實型型))進進行行不不同同的的處處理理,,這這就就是是函函數(shù)數(shù)重重載載;;public:Time(int,int,int);~Time()…………};Time::Time(inth,intm,ints){hour=h;minute=m;second=s;}Time::~Time(){…………例Voidmain(void){Timet1(10,20,30);//調(diào)調(diào)用用構(gòu)構(gòu)造造函函數(shù)數(shù)……………………}//調(diào)調(diào)用用析析構(gòu)構(gòu)函函數(shù)數(shù)理解解面面向向?qū)ο笙笤O(shè)設(shè)計計的的思思想想例::計計算算一一個個矩矩形形的的面面積積和和周周長長計算算一一個個矩矩形形的的面面積積和和周周長長從面面向向過過程程的的角角度度出出發(fā)發(fā)思思考考這這個個問問題題;;先確確定定面面積積和和周周長長的的算算法法((這這個個很很簡簡單單,,小小學(xué)學(xué)知知識識))編編寫寫2個個方方法法分分別別計計算算面面積積和和周周長長,,在在一一個個類類里里面面考考慮慮到到計計算算周周長長和和面面積積需需要要至至少少2個個參參數(shù)數(shù),,長長和和寬寬;;程序序如如下下::intperimeter(intlength,intwidth){return2*(length+width);}intarea(intlength,intwidth){returnlength*width;}voidmain(){cout<<perimeter(4,5);cout<<““\n””cout<<area(4,5);}下面面再再從從面面向向?qū)ο笙蟮牡慕墙嵌榷瘸龀霭l(fā)發(fā),,重重新新考考慮慮這這個個問問題題::一個個長長方方形形可可以以看看成成一一個個長長方方形形對對象象。。既既然然是是對對象象,,那那么么它它就就有有屬屬性性((長長和和寬寬))和和行行為為((周周長長和和面面積積))抽抽取取長長方方形形的的共共性性,,設(shè)設(shè)計計一一個個類類通通過過對對象象的的行行為為,,就就可可以以求求出出某某個個具具體體的的長長方方形形對對象象的的周周長長和和面面積積classRectangle(){public:intlength,width;intperimeter(){return2*(length+width);}intarea(){returnlength*width;}}voidmain(){Rectanglerect1=newRectangle();rect1.length=10;rect1.width=5;cout<<rect1.perimeter();cout<<rect1.area();}在C方方案案中中擴擴展展困困難難,,原原因因就就在在于于沒沒有有一一個個合合適適的的位位置置來來存存儲儲輔輔助助的的狀狀態(tài)態(tài)信信息息,,因因為為在在原原來來的的情情況況下下根根本本不不需需要要狀狀態(tài)態(tài)信信息息;;對象象提提供供了了一一個個理理想想的的位位置置來來放放置置狀狀態(tài)態(tài)信信息息,,并并且且作作為為對對象象的的一一部部分分是是顯顯示示可可用用的的,,而而不不是是隱隱藏藏在在幕幕后后的的東東西西;;繼續(xù)思考面向向?qū)ο蟮奶攸c點在面向過程的的思想里,一一個程序一般般都是由一個個個函數(shù)組成成的,這些函函數(shù)之間相互互調(diào)用,就就形成了一個個完整的程序序,解決了一一個問題。它它的基本結(jié)構(gòu)構(gòu)是:函數(shù)一(){……;}函數(shù)二(){……;}……主函數(shù)(){……;}在面向?qū)ο蟮牡乃枷胫?,是是把這些都封封裝起來,形形成一個類。。class類類名{函數(shù)一(){……;}函數(shù)二(){……;}……}然后由這個類類產(chǎn)生一個對對象,比如::我們把一個個類的類名起起為student那么產(chǎn)生對象象的方法就是是:students1;這里s1是一一個對象,產(chǎn)產(chǎn)生了這個對對象以后,才才可以進行相相關(guān)操作。操作方法如::s1.函函數(shù)一();;假設(shè)我們要做做一個小游戲戲,類似于網(wǎng)網(wǎng)游里面的打打怪,為簡單單起見,認(rèn)為為怪不打人,,只讓人打,,他的血不斷斷減少,直到到死亡。把所有怪物的的共同特征抽抽象出來,于于是我們得到到一個類:怪怪物class怪怪物{char怪怪物名;int血;;}怪物::怪物物(怪物名n,血n)/*構(gòu)造函函數(shù)*/{怪物名=怪物物名n;血=血n;}怪物::被打打函數(shù)(){血減少;}怪物::判斷斷函數(shù)(){if(血==0)cout<<“你勝利了了!”;}怪物::玩游游戲(){while(血>0){被打函數(shù)();判斷函數(shù)();}main主函函數(shù)voidmain(){/******產(chǎn)生對象象******/怪物怪物1("狼",,5000);怪物怪物2("虎",,8000);怪物怪物3("蛇",,3000);怪物1.玩游游戲();怪物2.玩游游戲();怪物3.玩游游戲();}指向?qū)ο蟊旧砩淼闹羔?,作作為隱含參數(shù)數(shù)傳給每個成成員函數(shù);例:

voidTime::showTime(){

cout<<hour<<’’:’<<minute<<‘:’’<<second<<endl;

}等同于于

voidTime::showTime(Time*this);{

cout<<this->hour<<‘‘:”<<this->minute……}指指針Time::showTime{

Display(this);

}Display(Time*pObj)This指針針對于在非本本類成員函數(shù)數(shù)中使用對象象成員變量需要讓多個對對象共享相同同值的成員時時使用;成員變量定義義:staticintm_ncount;使用和一般成成員變量一樣樣,也有公有有、私有之分分;初始化必須在在類定義的外外部:

intPerson::m_nCount=0;靜靜態(tài)成員成員函數(shù)也可可以是靜態(tài)的的;定義staticintGetCount();沒有this指針;可以通過類調(diào)調(diào)用:Person::GetCount();

也可以以通過對象調(diào)調(diào)用:e1.GetCount();靜態(tài)成員函數(shù)數(shù)只能訪問類類的靜態(tài)成員員;如需訪問非靜靜態(tài)成員,需需將對象作為為參數(shù)傳入;;

longPerson::GetID(Personx);;友友元友元函數(shù):訪訪問其他類的的私有成員變變量的函數(shù);;一個類可以聲聲明一個函數(shù)數(shù)為其友元函函數(shù);作用:編程方方便;定義:classA

{friendvoiddisplay(A);

private:

inta;}voiddisplay(Ae)

{cout<<e.a

}voidmain()

{………display(a1);}classB

{public:voidfun1(A&)

}classA

{friendvoidB::fun1(A&);

private:inta;

}

voidB::fun1(A&e)

{e.a=10;………}一個類的成員員函數(shù)作為另另一個類的友友元函數(shù)voidmain()

{Aa1;Bb1;b1.fun1(a1);

}友元類:類A可以聲明類類B為其友元元類,類B的的所有成員函函數(shù)都可以訪訪問A的所有有成員;定義

classC{public:voidfun2(A&);

}classA

{friendC;

private:inta;}voidC::fun2(A&e){

e.a=10;

}

voidmain(){Aa1;Cc1;c1.fun2(a1);

}classB

{public:voidfun1(A&);}

voidB::fun1(A&e)

{e.a=10;}

voidmain(){Aa1;Bb1;b1.fun1(a1);voidB::fun1(Ae)

{e.a=10;}

voidmain(){Aa1;Bb1;b1.fun1(a1);classB

{public:voidfun1(A)}classB

{public:voidfun1(A&);}

voidB::fun1(A&e)

{e.a=10;}

voidmain(){Aa1;Bb1;b1.fun1(a1);a1.ae.avoidB::fun1(Ae){e.a=10;}voidmain(){Aa1;Bb1;b1.fun1(a1);classB{public:voidfun1(A)}a1.ae.a3.3類類的繼繼承實現(xiàn)代代碼重重用和和擴充充;拷貝代代碼受受到版版權(quán)的的各方方面因因素影影響;;基基類和和派生生類在繼承承關(guān)系系中,,新定定義的的類稱稱為被被繼承承類的的派生生類或或子類類,被被繼承承的類類稱為為新定定義類類的基基類或或父類類;格式::class<派生生類名名>::[<派生生方式式>]<基類類名>{………};;派生方方式::public、private和protected(默默認(rèn)為為private));無論何何種派派生方方式,,基類類的私私有成成員都都不能能在派派生類類中使使用;;例classA{private:inta;public:intGeta(){returna};}classB:publicA{}voidmain(){Bb1;b1.Geta();b1.a:=3;}classB{private:inta;public:intGeta(){returna};}思考::如果果不采采用繼繼承定定義B類??classB:publicA{}public派派生::基類類成員員訪問問權(quán)限限不變變,可可以通通過派派生類類對象象訪問問基類類公有有成員員;private派生生:基基類所所有成成員成成為私私有成成員,,只能能通過過派生生類的的成員員函數(shù)數(shù)訪問問基類類非私私有成成員;;protected派生生:和和private差差不多多;例classA{private:inta;public:intGeta(){returna};}classB:A{…………}voidmain(){Bb1;b1.Geta();//非非法}基類中中不適適合派派生類類的成成員可可以在在派生生類中中重新新定義義,稱稱為覆覆蓋(override);;在派生生類中中定義義與基基類成成員函函數(shù)名名稱和和參數(shù)數(shù)表相相同的的函數(shù)數(shù);例classA{public:voidshow(){………}};classB:publicA{public:voidshow(){………}};………Bb1;b1.show();若需要要在派派生類類中調(diào)調(diào)用基基類中中同名名的成成員函函數(shù),,可以以使用用作用用域限限定符符“::””;classB:publicA{public:voidshow(){………};voiddisplay(){A::show();};};…………Bb1;b1.show();b1.display();基基類和和派生生類的的構(gòu)造造函數(shù)數(shù)當(dāng)程序序創(chuàng)建建一個個派生生類對對象時時,系系統(tǒng)首首先自自動創(chuàng)創(chuàng)建一一個基基類對對象,,即在在調(diào)用用派生生類的的構(gòu)造造函數(shù)數(shù)構(gòu)建建派生生類對對象時時,系系統(tǒng)首首先調(diào)調(diào)用基基類的的構(gòu)造造函數(shù)數(shù)構(gòu)建建基類類對象象;當(dāng)派生生類對對象的的生存存期結(jié)結(jié)束時時,首首先調(diào)調(diào)用派派生類類的析析構(gòu)對對象,,然后后調(diào)用用基類類的析析構(gòu)函函數(shù);;派生類類中必必須顯顯示調(diào)調(diào)用基基類的的構(gòu)造造函數(shù)數(shù),除除非基基類有有默認(rèn)認(rèn)的構(gòu)構(gòu)造函函數(shù);;例:B::B(<形參參聲明明>):A(<參數(shù)數(shù)表>){…………}形參時時指明明派生生類構(gòu)構(gòu)造函函數(shù)形形參的的名稱稱和類類型,,參數(shù)數(shù)表時時形參參說明明中所所給出出的部部分參參數(shù),,是要要傳遞遞給基基類構(gòu)構(gòu)造函函數(shù)的的參數(shù)數(shù);Point(inta,intb)Circle(inta,intb,intr):Point(a,b)Cylinder(inta,intb,intr,inth):Circle(a,b,r)多多重繼繼承單繼承承:每每個派派生類類只有有一個個直接接基類類;多重繼繼承::一個個派生生類可可以同同時從從多個個基類類派生生而來來;格式::class<B>:[<派派生方方式>]<A1>,,[<派生生方式式>]<A2>,……,[<派派生方方式>]<An>{…………};P86例例3-11GetAB(){returna+b;}虛虛基類類解決二二義性性問題題;每個派派生類類對象象含有有基類類的數(shù)數(shù)據(jù)成成員的的一個個副本本,因因此派派生類類對象象可能能存在在間接接基類類的兩兩份副副本。。采用虛虛基類類解決決;格式((派生生類定定義))classB:publicvirtualA基類定定義不不變;;3.4多多態(tài)性性和虛虛函數(shù)數(shù)多態(tài)性性:根根據(jù)數(shù)數(shù)據(jù)不不同進進行不不同的的運算算處理理,如如加法法,對對于實實數(shù)或或整數(shù)數(shù)就是是將兩兩數(shù)相相加,,對于于復(fù)數(shù)數(shù)就是是將對對應(yīng)的的實部部和虛虛部相相加;;“一種種接口口、多多種方方法””;多態(tài)性性分為為編譯譯時多多態(tài)性性和運運行時時多態(tài)態(tài)性;;編譯時時多態(tài)態(tài)性又又稱靜靜態(tài)多多態(tài)性性,用用來處處理函函數(shù)名名相同同,但但參數(shù)數(shù)類型型不同同的情情況,,通過過重載載機制制來實實現(xiàn);;運行時時多態(tài)態(tài)性::處理理函數(shù)數(shù)名、、參數(shù)數(shù)和返返回值值都相相同的的情況況,通通過虛虛函數(shù)數(shù)機制制實現(xiàn)現(xiàn);派生類類的對對象也也可以以認(rèn)為為是其其基類類的對對象,,但基基類的的對象象不是是其派派生類類的對對象;;(兒兒子像像老爸爸)允許基基類對對象的的指針針指向向其派派生類類的對對象,,通過過該指指針只只能訪訪問派派生類類中從從基類類繼承承的公公有成成員;;(老老爸的的東西西也是是兒子子的東東西,,老爸爸只能能拿老老爸自自己的的東西西)可以通通過強強制類類型轉(zhuǎn)轉(zhuǎn)換將將基類類指針針和派派生類類指針針互相相轉(zhuǎn)換換;用用基類類指針針指向向派生生類對對象例:…………classB:publicA…………voidsetB()………Aa,*pa;Bb,*pb;pa=&b;//基類類指針針指向向派生生類對對象pb=(B*)pa;//強強制類類型轉(zhuǎn)轉(zhuǎn)換pa->setB();//通通過基基類指指針訪訪問派派生類類自定定義的的成員員pb=&a//派派生類類指針針指向向基類類對象象pa=&a;pb=(B*)pa;pb->setB();//對對象a中不不存在在setB()虛虛函數(shù)數(shù)派生類類成員員函數(shù)數(shù)和基基類成成員函函數(shù)具具有相相同的的函數(shù)數(shù)名和和參數(shù)數(shù)類型型,派派生類類的成成員函函數(shù)將將覆蓋蓋基類類成員員函數(shù)數(shù);例:classA{voidshow()…………classB:publicA{voidshow()……Bb;b.show();若用基基類指指針指指向派派生類類對象象,結(jié)結(jié)果一一樣;;A*pa;Bb;pa=&b;pa->show();在基類類對象象中使使用虛虛函數(shù)數(shù),可可以使使指向向派生生類對對象的的基類類指針針調(diào)用用派生生類中中的覆覆蓋函函數(shù)((和基基類對對象成成員函函數(shù)同同名));派生類類對象象的覆覆蓋函函數(shù)各各不相相同,,但基基類對對象的的虛函函數(shù)機機制,,使我我們可可以通通過指指向派派生類類對象象的基基類指指針調(diào)調(diào)用同同個函函數(shù)名名,實實現(xiàn)不不同派派生類類對象象的不不同功功能,,這就就是類類的多多態(tài)性性;格式::classA{public:virtualvoidshow(){………};}classB:publicA{public:voidshow(){………};}voidmain{A*pa;Bb;pa=&b;pa->show();}利用虛虛函數(shù)數(shù)機制制,我我們可可以在在基類類和派派生類類中使使用相相同的的函數(shù)數(shù)名和和參數(shù)數(shù)類型型,而而定義義不同同的操操作;;為同一一個類類體系系中所所有派派生類類的同同一類類行為為提供供了統(tǒng)統(tǒng)一的的接口口;CShape.showCCircle.showCSquare.showCEllipse.show如果用用new運運算創(chuàng)創(chuàng)建派派生類類對象象;當(dāng)當(dāng)delete運算算撤銷銷派生生類對對象時時,只只調(diào)用用基類類的析析構(gòu)函函數(shù),,沒有有調(diào)用用派生生類的的析構(gòu)構(gòu)函數(shù)數(shù);定義基基類的的析構(gòu)構(gòu)函數(shù)數(shù)為虛虛函數(shù)數(shù)可解解決問問題;;格式::classA{virtual~A(){………};}classB:publicA{~B(){………};}voidmain(){A*pa=newB;…………deletepa;}開發(fā)程程序中中,常常將基基類中中功能能容易易變化化的成成員函函數(shù)設(shè)設(shè)計成成虛函函數(shù),,然后后根據(jù)據(jù)需要要設(shè)計計派生生類的的虛函函數(shù),,實現(xiàn)現(xiàn)“一一種接接口、、多種種方法法”;;抽抽象類類和純純虛函函數(shù)我們可可以讓讓基類類的一一些成成員函函數(shù)沒沒有具具體的的定義義,這這種基基類只只能用用于類類的繼繼承,,其本本身不不能用用來創(chuàng)創(chuàng)建對對象,,這樣樣的類類稱為為抽象象類;;抽象類類只能能是基基類,,它提提供了了一個個框架架,僅僅僅起起著統(tǒng)統(tǒng)一接接口的的作用用;不能聲聲明抽抽象類類的對對象,,但可可以聲聲明抽抽象類類的指指針;;抽象類類:1、至至少有有一個個成員員函數(shù)數(shù)不定定義具具體實實現(xiàn);;2、、定義義了一一個protected訪問問屬性性的構(gòu)構(gòu)造函函數(shù)或或析構(gòu)構(gòu)函數(shù)數(shù);不定義義具體體實現(xiàn)現(xiàn)的成成員函函數(shù)稱稱為純純虛函函數(shù);;純虛函函數(shù)不不能調(diào)調(diào)用;;格式::virtual<數(shù)據(jù)據(jù)類型型><成員員函數(shù)數(shù)名>(<形參參表>)=0;例:classA{public:virtualvoidfun1()=0;};classB:publicA{public:voidfun1(){………};}3.5重重載C++重載載分為為函數(shù)數(shù)重載載和運運算符符重載載;運算可可以理理解為為是調(diào)調(diào)用一一個函函數(shù);;使用重重載機機制可可以對對一個個函數(shù)數(shù)名((或運運算符符)定定義多多個函函數(shù)((或運運算)),只只不過過函數(shù)數(shù)的參參數(shù)((或運運算的的數(shù)))類型型不同同;如加法法,對對于實實數(shù)或或整數(shù)數(shù)就是是將兩兩數(shù)相相加,,對于于復(fù)數(shù)數(shù)就是是將對對應(yīng)的的實部部和虛虛部相相加;;函函數(shù)重重載我們可可以通通過函函數(shù)重重載機機制使使一組組功能能相似似但函函數(shù)參參數(shù)類類型不不同的的函數(shù)數(shù)共用用一個個函數(shù)數(shù)名;;C++編譯譯器根根據(jù)參參數(shù)類類型和和個數(shù)數(shù)選擇擇正確確的函函數(shù);;P95例3-18求求絕對對值函函數(shù)abs()重載載;不能利利用函函數(shù)返返回類類型的的不同同進行行函數(shù)數(shù)的重重載;;不能利利用引引用來來重載載;對對于于voidfun(int&);和和voidfun(int);;fun(i)無無法選選擇調(diào)調(diào)用哪哪個函函數(shù);;利用重重載可可以設(shè)設(shè)計多多個構(gòu)構(gòu)造函函數(shù),,為對對象提提供多多種初初始化化方式式;P96例3-19::classBox{public:Box(){………};Box(int,int,int){………};}………Boxbox1;BoxBox2(10,15,20);運運算符符重載載運算符符重載載指對對于不不同數(shù)數(shù)據(jù)類類型的的操作作數(shù),,同一一個運運算符符所代代表的的運算算功能能可以以不同同;可以把把運算算符看看成調(diào)調(diào)用運運算符符函數(shù)數(shù),如如10+20看看成int+(10,20);;重載運運算符符就是是編寫寫運算算符函函數(shù);;格式<數(shù)數(shù)據(jù)類類型>operator<運算算符>(<形參參表>);P97例3-20非非成員員函數(shù)數(shù)重載載運算算符::classComplex{………}Complexoperator+(Complexc1,Complexc2){…………}voidmain(){………complex=complex1+complex2;}利用非非成員員函數(shù)數(shù)重載載雙目目運算算符時時,運運算符符函數(shù)數(shù)的第第一個個參數(shù)數(shù)代表表運算算符左左邊的的操作作數(shù),,運算算符函函數(shù)的的第二二個參參數(shù)代代表運運算符符右邊邊的操操作數(shù)數(shù);Complexoperator+(Complexc1,Complexc2)如果運運算符符函數(shù)數(shù)要求求訪問問一個個類的的非公公有成成員,,則運運算符符函數(shù)數(shù)不能能定義義為非非成員員函數(shù)數(shù),除除非將將它聲聲明為為該類類的友友元函函數(shù);;P98例3-21成成員函函數(shù)重重載運運算符符:classComplex{Complexoperator+(Complex);}ComplexComplex::operator+(Complexother){…………}voidmain(){………complex=complex1+complex2;}利用成成員函函數(shù)重重載雙雙目運運算符符時,,運算算符左左邊的的操作作數(shù)就就是對對象本本身,,不能能再將將它作作為運運算符符函數(shù)數(shù)的參參數(shù),,因此此,這這時運運算符符函數(shù)數(shù)只需需一個個函數(shù)數(shù)參數(shù)數(shù);Complexoperator+(Complex);同一個個重載載運算算符的的參數(shù)數(shù)個數(shù)數(shù)是相相同的的;用戶不不能定定義新新的運運算符符,只只能對對現(xiàn)有有的進進行重重載;;重載后的優(yōu)先先級和結(jié)合性性不變;下列運算符不不能重載““.”(成員員運算符)““::”(

溫馨提示

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

評論

0/150

提交評論