《CC++語(yǔ)言程序設(shè)計(jì)》課件第12章 多態(tài)性_第1頁(yè)
《CC++語(yǔ)言程序設(shè)計(jì)》課件第12章 多態(tài)性_第2頁(yè)
《CC++語(yǔ)言程序設(shè)計(jì)》課件第12章 多態(tài)性_第3頁(yè)
《CC++語(yǔ)言程序設(shè)計(jì)》課件第12章 多態(tài)性_第4頁(yè)
《CC++語(yǔ)言程序設(shè)計(jì)》課件第12章 多態(tài)性_第5頁(yè)
已閱讀5頁(yè),還剩83頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第十二章多態(tài)性12.1多態(tài)性概述12.2函數(shù)重載12.3運(yùn)算符重載12.4虛函數(shù)12.5抽象類12.6綜合實(shí)例——俄羅斯方塊游戲12.7小結(jié)12.1多態(tài)性概述靜態(tài)聯(lián)編動(dòng)態(tài)聯(lián)編?kù)o態(tài)多態(tài)性(編譯時(shí)多態(tài)性)動(dòng)態(tài)多態(tài)性(運(yùn)行時(shí)多態(tài)性)12.2函數(shù)重載編譯時(shí)的多態(tài)性可以通過(guò)函數(shù)重載實(shí)現(xiàn).函數(shù)重載有兩種情況:參數(shù)有所差別的重載函數(shù)所帶參數(shù)完全相同,只是它們屬于不同的類【例12.1】在基類和派生類中重載函數(shù)#include<iostream.h>classbase{ intx,y;public: base(inta,intb) {x=a;y=b;} voidshow()//基類中的show()函數(shù) { cout<<"執(zhí)行基類中的show()函數(shù)"<<endl; cout<<x<<","<<y<<endl; }};classderived:publicbase{ intz;public: derived(inta,intb,intc):base(a,b) { z=c;} voidshow()//派生類中的show()函數(shù) { cout<<"執(zhí)行派生類中的show()函數(shù)"<<endl; cout<<z<<endl; }};voidmain(){ baseb(20,20); derivedd(8,8,30); b.show();//執(zhí)行基類中的show()函數(shù) d.show();//執(zhí)行派生類中的show()函數(shù) d.base::show();//執(zhí)行基類中的show()函數(shù) }

在基類和派生類中進(jìn)行函數(shù)重載時(shí),在編譯時(shí)可以用下面兩種方法區(qū)別重載函數(shù):使用對(duì)象名加以區(qū)分。例如:b.show()和d.show()分別調(diào)用類base和derived的show()函數(shù)。使用“類名::”加以區(qū)分。例如:d.base::show()調(diào)用的是base的show()函數(shù)。12.3運(yùn)算符重載自定義的類的運(yùn)算往往用運(yùn)算符重載函數(shù)來(lái)實(shí)現(xiàn)運(yùn)算符重載的目的:擴(kuò)充語(yǔ)言的功能,即將運(yùn)算符擴(kuò)充到用戶定義的類型上去。運(yùn)算符重載通過(guò)創(chuàng)建運(yùn)算符函數(shù)operator()來(lái)實(shí)現(xiàn)??梢灾剌d成為類的成員,也可是類的友元。12.3.1運(yùn)算符重載的規(guī)則為了表達(dá)方便,人們希望能對(duì)自定義的類型進(jìn)行運(yùn)算,希望內(nèi)部運(yùn)算符(如“+”、“-”、“*”、“/”等)在特定的類對(duì)象上以新的含義進(jìn)行解釋,即實(shí)現(xiàn)運(yùn)算符的重載。C++為運(yùn)算符重載提供了一種方法,使用以下形式進(jìn)行運(yùn)算符重載:

其中,@表示要重載的運(yùn)算符,type是返回類型。typeoperator@(參數(shù)表);除了“.”、“.*”、“::”、“?:”、“#”、“#?!逼渌伎梢灾剌d。delete、new、指針、引用也可以重載。運(yùn)算符函數(shù)可以定義為內(nèi)聯(lián)函數(shù)。用戶定義的運(yùn)算符不改變運(yùn)算符的優(yōu)先次序。不可以定義系統(tǒng)定義的運(yùn)算符集之外的運(yùn)算符。不能改變運(yùn)算符的的語(yǔ)法結(jié)構(gòu)?!纠?2.2】使用運(yùn)算符重載函數(shù)將類對(duì)象相加。

#include<iostream.h> classcomplex{ public: doublereal; doubleimag; complex(doubler=0,doublei=0) {real=r;imag=i;} }; complexoperator+(complexco1,complexco2) { complextemp; temp.real=co1.real+co2.real; temp.imag=co1.imag+co2.imag; returntemp; } main() { complexcom1(1.1,2.2),com2(3.3,4.4),total1,total2; total1=operator+(com1,com2);//調(diào)用運(yùn)算符函數(shù)operater+()的第一種方式 cout<<"real1="<<total1.real<<"“

<<"imag1="<<total1.imag<<endl; total2=com1+com2;//調(diào)用運(yùn)算符函數(shù)operater+()的第二種方式

cout<<"real2="<<total2.real<<"“

<<"imag2="<<total2.imag<<endl; return0; }12.3.2運(yùn)算符重載為成員函數(shù)成員運(yùn)算符定義的語(yǔ)法形式

classX{//…typeoperator@(參數(shù)表);//…};typeX::operator@(參數(shù)表){//函數(shù)體}1.雙目運(yùn)算符重載為成員函數(shù)成員運(yùn)算符函數(shù)的參數(shù)表中只有一個(gè)參數(shù),它作為運(yùn)算符的右操作數(shù),此時(shí)當(dāng)前對(duì)象作為運(yùn)算符的左操作數(shù),它是通過(guò)this指針隱含的傳遞給函數(shù)的。aa@bb;//隱式調(diào)用aa.operator@(bb);//顯式調(diào)用例12.3

雙目運(yùn)算符重載為成員函數(shù)應(yīng)用。2.單目運(yùn)算符重載為成員函數(shù)成員運(yùn)算符函數(shù)的參數(shù)表中沒(méi)有參數(shù),此時(shí)當(dāng)前對(duì)象作為運(yùn)算符的一個(gè)操作數(shù)

@aa//隱式調(diào)用aa.operator@();//顯式調(diào)用例12.4

單目運(yùn)算符重載為成員函數(shù)應(yīng)用。12.3.3友元運(yùn)算符函數(shù)友元運(yùn)算符函數(shù)定義的語(yǔ)法形式類內(nèi):friendtypeoperator@(參數(shù)表);

類外:

typeoperator@(參數(shù)表){//函數(shù)體}1.雙目運(yùn)算符重載為友元函數(shù)當(dāng)用友元函數(shù)重載雙目運(yùn)算符時(shí),兩個(gè)操作數(shù)都要傳遞給運(yùn)算符函數(shù),調(diào)用時(shí)可采用以下兩種方式:

aa@bb;//隱式調(diào)用,aa和bb分別為左、右操作數(shù)

operator@(aa,bb);//顯式調(diào)用雙目友元運(yùn)算符函數(shù)operator@所需要的兩個(gè)操作數(shù)都在參數(shù)表中由對(duì)象aa和bb顯式調(diào)用。例12.5雙目運(yùn)算符重載為友元函數(shù)。2.單目運(yùn)算符重載為友元函數(shù)當(dāng)用友元函數(shù)重載單目運(yùn)算符時(shí),需要一個(gè)顯式的操作數(shù),調(diào)用時(shí)可采用以下兩種方式:@aa;//隱式調(diào)用,aa為操作數(shù)operator@(aa);//顯式調(diào)用例12.6單目運(yùn)算符重載為友元函數(shù)應(yīng)用。注意:使用友元運(yùn)算符重載“++”、“--”這樣的運(yùn)算符,可能會(huì)出現(xiàn)一些問(wèn)題。不能用友元函數(shù)重載的運(yùn)算符是:=、()、[]、->,其余的運(yùn)算符都可以使用友元函數(shù)來(lái)實(shí)現(xiàn)成員運(yùn)算符函數(shù)與友元運(yùn)算符函數(shù)的比較對(duì)雙目運(yùn)算符而言,成員運(yùn)算符函數(shù)帶有一個(gè)參數(shù),友元運(yùn)算符函數(shù)帶由兩個(gè)參數(shù);對(duì)單目運(yùn)算符而言,成員運(yùn)算符函數(shù)不帶參數(shù),而友元運(yùn)算符函數(shù)帶一個(gè)參數(shù)。雙目運(yùn)算符一般可被重載為友元運(yùn)算符函數(shù)或成員運(yùn)算符函數(shù),但有一種情況,必須使用友元函數(shù)。在左操作數(shù)為系統(tǒng)預(yù)定義數(shù)據(jù)類型,或必須為一個(gè)不同的類對(duì)象時(shí)。一般而言,對(duì)于雙目運(yùn)算符,將它重載為一個(gè)友元函數(shù)比重載為一個(gè)成員函數(shù)便于使用。若一個(gè)運(yùn)算符的操作需要修改類對(duì)象的狀態(tài),則選擇成員運(yùn)算符函數(shù)較好。如果運(yùn)算符所需的操作數(shù)(尤其是第一個(gè)操作數(shù))希望有隱式轉(zhuǎn)換,則運(yùn)算符重載必須使用友元函數(shù)。12.3.4“++”和“--”的重載前綴方式和后綴方式聲明不同運(yùn)算符“++”和“--”作前綴和后綴是有區(qū)別的。但是,C++V2.1之前的版本在重載“++”或“--”時(shí),不能顯示區(qū)分是前綴方式還是后綴方式。在C++V2.1及以后的版本中,編輯器可以通過(guò)在運(yùn)算符函數(shù)表中是否插入關(guān)鍵字int來(lái)區(qū)分這兩種方式。例12.7運(yùn)算符“++”和“--”作前綴和后綴重載。12.4虛函數(shù)虛函數(shù)是重載的另一種表現(xiàn)形式。虛函數(shù)允許函數(shù)調(diào)用與函數(shù)體之間的聯(lián)系在運(yùn)行時(shí)才建立,也就是在運(yùn)行時(shí)才決定如何動(dòng)作,即所謂的動(dòng)態(tài)聯(lián)編。12.4.1引入派生類后的對(duì)象指針聲明為指向基類對(duì)象的指針可以指向它的公有派生的對(duì)象,但不允許指向它的私有派生對(duì)象。允許將一個(gè)聲明為指向基類的指針指向其公有派生類的對(duì)象,但是不能將一個(gè)聲明為指向派生類對(duì)象的指針指向其基類的對(duì)象。聲明為指向基類對(duì)象的指針,當(dāng)其指向其公有派生類對(duì)象時(shí),只能用它來(lái)直接訪問(wèn)派生類中從基類繼承來(lái)的成員,而不能直接訪問(wèn)公有派生類中定義的成員。12.4.2虛函數(shù)的定義及使用虛函數(shù)的作用

“同一接口,多種方法”虛函數(shù)的定義在基類中被關(guān)鍵字virtual說(shuō)明,并在派生類中重新定義的函數(shù)。在派生類中重新定義時(shí),其函數(shù)原型,包括返回類型、函數(shù)名、參數(shù)個(gè)數(shù)與參數(shù)類型的順序,都必須與基類中的原型完全相同。例12.9使用虛函數(shù)實(shí)現(xiàn)動(dòng)態(tài)多態(tài)性。說(shuō)明:在基類中,用關(guān)鍵字virtual可以將其public或protected部分的成員函數(shù)聲明為虛函數(shù)。在派生類對(duì)基類中聲明的虛函數(shù)進(jìn)行重新定義時(shí),關(guān)鍵字virtual可以寫也可以不寫。虛函數(shù)被重新定義時(shí),其函數(shù)的原型與基類中的函數(shù)原型必須完全相同。一個(gè)虛函數(shù)無(wú)論被公有繼承多少次,它仍然保持虛函數(shù)的特性。虛函數(shù)必須是其所在類的成員函數(shù),而不能是友元函數(shù),也不能是靜態(tài)成員函數(shù),因?yàn)樘摵瘮?shù)調(diào)用要靠特定的對(duì)象來(lái)決定該激活哪個(gè)函數(shù)。但是虛函數(shù)可以在另一個(gè)類中被聲明為友元函數(shù)。12.4.3虛析構(gòu)函數(shù)構(gòu)造函數(shù)不能是虛函數(shù),但析構(gòu)函數(shù)可以是虛函數(shù)。例12.10析構(gòu)函數(shù)定義不當(dāng)造成內(nèi)存泄漏。#include"iostream.h"classA{public: int*a; A(){a=new(int);} virtualvoidfunc1(){} ~A(){deletea;cout<<"deletea"<<endl;}};classB:publicA{public: int*b; B(){b=new(int);} virtualvoidfunc1(){} ~B(){deleteb;cout<<"deleteb"<<endl;}};voidmain(){ A*pb=newB(); deletepb;}

在main函數(shù)中,動(dòng)態(tài)創(chuàng)建了一個(gè)B類對(duì)象。當(dāng)B對(duì)象創(chuàng)建時(shí),調(diào)用的是B類的構(gòu)造函數(shù)。但是,當(dāng)對(duì)象析構(gòu)時(shí),卻調(diào)用的是A類的析構(gòu)函數(shù),B類的析構(gòu)函數(shù)沒(méi)有被調(diào)用,因而發(fā)生了內(nèi)存泄漏,這是不希望看到的。造成這種問(wèn)題的原因是:當(dāng)A類指針指向的內(nèi)存單元(即B類對(duì)象的數(shù)據(jù))被釋放時(shí),編譯器看到指針類型是A類的,所以調(diào)用A類的析構(gòu)函數(shù)。其實(shí),這個(gè)時(shí)候需要調(diào)用指針?biāo)赶虻膶?duì)象類型的析構(gòu)函數(shù)即B類的析構(gòu)函數(shù)。虛函數(shù)能夠滿足這個(gè)要求。所以,可以使用虛析構(gòu)函數(shù)來(lái)解決上面遇到的問(wèn)題:【例12.11】虛析構(gòu)函數(shù)的使用。

#include"iostream.h" classA{ public: int*a; A(){a=new(int);} virtualvoidfunc1(){} virtual~A(){deletea;cout<<"deletea"<<endl;} };

classB:publicA{ public: int*b; B(){b=new(int);} virtualvoidfunc1(){} virtual~B(){deleteb;cout<<"deleteb"<<endl;} }; voidmain() { A*pb=newB(); deletepb; }應(yīng)用舉例應(yīng)用C++的多態(tài)性,計(jì)算三角形、矩形和圓的面積。12.5抽象類純虛函數(shù)是一個(gè)在基類中說(shuō)明的虛函數(shù),它在基類中沒(méi)有定義,但要求在它的派生類中定義自己的版本,或重新說(shuō)明為純虛函數(shù)。純虛函數(shù)的一般形式如下:virtualtype函數(shù)名(參數(shù)表)=0;【例12.12】用虛函數(shù)求三角形和矩形面積。#include<iostream.h>classShape{protected:intwidth,height;public:voidset_values(inta,intb){width=a;height=b;}virtualintarea(){cout<<"Noarea"<<endl;}};classCRectangle:publicShape{public:intarea(void){return(width*height);}};classCTriangle:publicShape{public:intarea(void){return(width*height/2);}};voidmain(){CRectanglerect;CTriangletrgl;Shape*ppoly1=▭Shape*ppoly2=&trgl;ppoly1->set_values(4,5);ppoly2->set_values(4,5);cout<<ppoly1->area()<<endl;cout<<ppoly2->area()<<endl;}抽象類如果一個(gè)類中至少包含一個(gè)純虛函數(shù),那么就稱該類為抽象類。對(duì)于抽象類有以下幾點(diǎn)規(guī)定:由于抽象類中至少包含有一個(gè)沒(méi)有定義功能的純虛函數(shù),因此抽象類只能用作其它類的基類,不能建立抽象類對(duì)象。抽象類不能用作參數(shù)類型、函數(shù)返回類型或顯示轉(zhuǎn)換的類型。但可以聲明指向抽象類的指針或引用,此指針可以指向它的派生類,進(jìn)而實(shí)現(xiàn)多態(tài)性。如果在抽象類的派生類中沒(méi)有重新說(shuō)明純虛函數(shù),而派生類只是繼承基類的純虛函數(shù),則這個(gè)派生類仍然還是一個(gè)抽象類。classshape{ //…public: //…virtualvoidshow()=0;}; shapes1; shape*ptr; shapef(); shapeg(shapes); shape&h(shape&);思考12.6綜合實(shí)例——俄羅斯方塊游戲綜合前面所學(xué)的知識(shí),熟悉面向?qū)ο蟪绦蛟O(shè)計(jì)的全過(guò)程,即面向?qū)ο蟮姆治?、面向?qū)ο蟮脑O(shè)計(jì)、面向?qū)ο蟮膶?shí)現(xiàn)三個(gè)過(guò)程,創(chuàng)建一個(gè)實(shí)用的游戲程序。游戲說(shuō)明及規(guī)則俄羅斯方塊是由俄羅斯人阿列克謝·帕基特諾夫發(fā)明的。俄羅斯方塊原名是俄語(yǔ)Тетрис(英語(yǔ)是Tetris),這個(gè)名字來(lái)源于希臘語(yǔ)tetra,意思是“四”,而游戲的作者最喜歡網(wǎng)球(tennis)。于是,他把兩個(gè)詞tetra和tennis合而為一,命名為Tetris,這也就是俄羅斯方塊名字的由來(lái)。游戲規(guī)則Tetris游戲在一個(gè)m*n的矩形框內(nèi)進(jìn)行。游戲開始時(shí),矩形框的頂部會(huì)隨機(jī)出現(xiàn)一個(gè)由四個(gè)小方塊構(gòu)成的磚塊,每過(guò)一個(gè)很短的時(shí)間(我們稱這個(gè)時(shí)間為一個(gè)tick),它就會(huì)下落一格,直到它碰到矩形框的底部,然后再過(guò)一個(gè)tick它就會(huì)固定在矩形框的底部,成為固定塊。接著再過(guò)一個(gè)tick頂部又會(huì)出現(xiàn)下一個(gè)隨機(jī)形狀,同樣每隔一個(gè)tick都會(huì)下落,直到接觸到底部或者接觸到下面的固定塊時(shí),再過(guò)一個(gè)tick它也會(huì)成為固定塊,再過(guò)一個(gè)tick之后會(huì)進(jìn)行檢查,發(fā)現(xiàn)有充滿方塊的行則會(huì)消除它,同時(shí)頂部出現(xiàn)下一個(gè)隨機(jī)形狀。直到頂部出現(xiàn)的隨機(jī)形狀在剛出現(xiàn)時(shí)就與固定塊重疊,表示游戲結(jié)束。操作說(shuō)明:a—左移

d—右移

w—翻轉(zhuǎn)

s—下移Tetris游戲的分析、設(shè)計(jì)與實(shí)現(xiàn)1.Tetris游戲的矩形框首先描述Tetris游戲的矩形框。矩形框類——CBin名稱:矩形框?qū)傩裕焊叨?/p>

寬度映像方法(操作):

構(gòu)造函數(shù)析構(gòu)函數(shù)

獲取矩形高度值獲取矩形寬度值獲取映像數(shù)據(jù)設(shè)置映像數(shù)據(jù)刪除整行classCBin{private:unsignedintwidth;unsignedintheight;unsignedchar**image;public:CBin(unsignedintw,unsignedinth);~CBin();unsignedintgetWidth(){returnwidth;}unsignedintgetHeight(){returnheight;}voidgetImage(unsignedchar**destImage);voidsetImage(unsignedchar**srcImage);unsignedintremoveFullLines();};矩形框類方法的實(shí)現(xiàn)構(gòu)造函數(shù)算法描述:用來(lái)初始化數(shù)據(jù)成員width和height為image分配空間并初始化CBin::CBin(unsignedintw,unsignedinth){ width=w; height=h; image=newunsignedchar*[height];for(unsignedinti=0;i<height;i++) {image[i]=newunsignedchar[width]; for(unsignedintj=0;j<width;j++) image[i][j]=0;}}析構(gòu)函數(shù)算法描述:刪除在構(gòu)造函數(shù)中為image分配的空間CBin::~CBin(){ for(unsignedinti=0;i<height;i++){deleteimage[i];}delete[]image;}函數(shù)功能:獲取映像數(shù)據(jù)算法描述:將游戲面板的源映像數(shù)據(jù)數(shù)據(jù)拷貝到目的映像中源映像:CBin類數(shù)據(jù)成員image:二維數(shù)組目的映像:同image大小相同的二維數(shù)組voidCBin::getImage(unsignedchar**destImage){for(unsignedinti=0;i<height;i++) for(unsignedintj=0;j<width;j++) destImage[i][j]=image[i][j];}函數(shù)功能:設(shè)置映像數(shù)據(jù)算法描述:將源映像數(shù)據(jù)數(shù)據(jù)拷貝到目的映像中源映像:同image大小相同的二維數(shù)組目的映像:CBin類數(shù)據(jù)成員image:二維數(shù)組voidCBin::setImage(unsignedchar**srcImage){ for(unsignedinti=0;i<height;i++) for(unsignedintj=0;j<width;j++) image[i][j]=srcImage[i][j];}自頂向下,逐步求精函數(shù)功能:刪除整行算法描述:第一步:根據(jù)函數(shù)功能,程序可以寫為:unsignedintCBin::removeFullLines(){檢查image的每一行是否被填滿,如果任何一行完全填滿,則刪除這一行,并讓上面行的數(shù)據(jù)下移一行,記錄刪除的總行數(shù)。返回刪除的總行數(shù)}第二步,對(duì)程序進(jìn)一步細(xì)化:unsignedintCBin::removeFullLines(){ unsignedintflag,EmptyLine=0;unsignedinti,j,m; for(i=0;i<height;i++)//循環(huán)遍歷image的每一行 {

檢查一行是否被填滿,如果任何一行完全填滿,則刪除這一行,并讓上面行的數(shù)據(jù)下移一行,記錄刪除的總行數(shù) }returnEmptyLine;//返回刪除的總行數(shù)}第三步對(duì)“檢查一行是否被填滿,如果任何一行完全填滿,則刪除這一行,并讓上面行的數(shù)據(jù)下移一行,記錄刪除的總行數(shù)”進(jìn)行細(xì)化。

//檢查一行是否被填滿

flag=0;

for(j=0;j<width;j++)

{

if(image[i][j]==0) flag=1; }//如果一行完全被填滿if(flag==0){

//刪除整行,依次下移

for(m=i;m>0;m--)for(j=0;j<width;j++) image[m][j]=image[m-1][j]; //最上面一行補(bǔ)0

for(j=0;j<width;j++)

image[0][j]=0;

EmptyLine++;//記錄刪除的行數(shù) }unsignedintCBin::removeFullLines(){ unsignedintflag,EmptyLine=0;unsignedinti,j,m; for(i=0;i<height;i++) { flag=0;

//檢查一行是否被填滿 for(j=0;j<width;j++) { if(image[i][j]==0) flag=1; }//一行完全被填滿if(flag==0){

//刪除整行,依次下移

for(m=i;m>0;m--)for(j=0;j<width;j++) image[m][j]=image[m-1][j]; for(j=0;j<width;j++) image[0][j]=0; EmptyLine++;//記錄刪除的行數(shù) }}returnEmptyLine;}現(xiàn)在來(lái)完成一些Tetris磚塊類。Tetris的常用磚塊見(jiàn)下圖。經(jīng)分析所有的磚塊都有共同的特征,因此可以定義一個(gè)所有磚塊共同的基類CBrick(可定義為抽象類)以“I”磚塊為例分析:CIBrick類有四個(gè)數(shù)據(jù)成員:orientation,posX,posY,andcolour。orientation表示了“I”磚塊的四個(gè)狀態(tài),可能的取值為{0,1,2,3},磚塊的狀態(tài)如圖所示,由狀態(tài)0到狀態(tài)1是“I”磚塊固定一個(gè)特定點(diǎn)順時(shí)針旋轉(zhuǎn)90度。依此類推,狀態(tài)3的下一個(gè)狀態(tài)是狀態(tài)0。posX,posY記錄了特定點(diǎn)(圖中黑點(diǎn))的坐標(biāo)。Colour為磚塊的顏色值。磚塊類——CBrick名稱:磚塊類屬性:狀態(tài)

位置X坐標(biāo)顏色位置Y坐標(biāo)方法(操作):

設(shè)置狀態(tài);獲取狀態(tài)

設(shè)置位置X坐標(biāo);獲取位置X坐標(biāo)

設(shè)置位置Y坐標(biāo);獲取位置Y坐標(biāo)

設(shè)置顏色;獲取顏色左移;右移;下移;旋轉(zhuǎn);沖突檢查;設(shè)置游戲面板;置頂(可設(shè)置成純虛函數(shù))磚塊類——CBrickclassCBrick{protected:intorientation;intposX;intposY;unsignedcharcolour;public:intgetOrientation(){returnorientation;};intgetPosX(){returnposX;};intgetPosY(){returnposY;};unsignedchargetColour(){returncolour;};

磚塊類——CBrickvoidsetOrientation(intnewOrient){orientation=newOrient;};voidsetPosX(intnewPosX){posX=newPosX;};voidsetPosY(intnewPosY){posY=newPosY;};voidsetColour(unsignedcharnewColour){colour=newColour;};磚塊類——CBrickintshiftLeft(CBin*bin);intshiftRight(CBin*bin);intshiftDown(CBin*bin);introtateClockwise(CBin*bin);virtualintcheckCollision(CBin*bin)=0;virtualvoidoperator>>(unsignedchar**binImage)=0;virtualvoidputAtTop(intnewOrient,intnewPosX)=0;};函數(shù)功能:左移算法描述:獲取特定點(diǎn)X坐標(biāo)重設(shè)特定點(diǎn)X坐標(biāo)為當(dāng)前值減1檢查沖突如果沖突,則不能左移,恢復(fù)特定點(diǎn)X坐標(biāo),返回0值否則,返回1值intCBrick::shiftLeft(CBin*bin){ intposX; posX=getPosX();setPosX(posX-1);if(checkCollision(bin)==0){setPosX(posX);return0;}return1;}函數(shù)功能:右移算法描述:獲取特定點(diǎn)X坐標(biāo)重設(shè)特定點(diǎn)X坐標(biāo)為當(dāng)前值加1檢查沖突如果沖突,則不能右移,恢復(fù)特定點(diǎn)X坐標(biāo),返回0值否則,返回1值intCBrick::shiftRight(CBin*bin){ intposX; posX=getPosX();setPosX(posX+1);if(checkCollision(bin)==0){ setPosX(posX);return0;}return1;}函數(shù)功能:下移算法描述:獲取特定點(diǎn)Y坐標(biāo)重設(shè)特定點(diǎn)Y坐標(biāo)為當(dāng)前值加1檢查沖突如果沖突,則不能下移,恢復(fù)特定點(diǎn)Y坐標(biāo),返回0值否則,返回1值intCBrick::shiftDown(CBin*bin){ intposY; posY=getPosY();setPosY(posY+1);if(checkCollision(bin)==0){ setPosY(posY);return0;}return1;}函數(shù)功能:旋轉(zhuǎn)算法描述:獲取磚塊狀態(tài)如果狀態(tài)為3,則旋轉(zhuǎn)后狀態(tài)為0;否則,旋轉(zhuǎn)后狀態(tài)為當(dāng)前值加1檢查沖突如果沖突,則不能旋轉(zhuǎn),恢復(fù)原狀態(tài),返回0值否則,返回1值intCBrick::rotateClockwise(CBin*bin){ intorientation,oldOrientation;orientation=getOrientation(); oldOrientation=orientation; if(orientation==3) orientation=0; else orientation=orientation+1;setOrientation(orientation); if(checkCollision(bin)==0){setOrientation(oldOrientation);return0;}return1;}“I”型磚塊類——CIBrickCIBrick從CBrick繼承而來(lái)需重載3個(gè)純虛函數(shù)classCIBrick:publicCBrick{public: intcheckCollision(CBin*bin); voidoperator>>(unsignedchar**binImage); voidputAtTop(intnewOrient,intnewPosX);};函數(shù)功能:檢查沖突算法描述:獲取游戲面板映像獲取當(dāng)前磚塊的狀態(tài)和特定點(diǎn)針對(duì)磚塊不同的狀態(tài)進(jìn)行檢查如果沖突,返回0值;否則,返回1值CIBrick::checkCollision函數(shù)的實(shí)現(xiàn)獲取游戲面板映像intCIBrick::checkCollision(CBin*bin){intwidth;intheight;unsignedchar**image; intorientation; intposX; intposY; width=bin->getWidth(); height=bin->getHeight(); image=newunsignedchar*[height];for(inti=0;i<height;i++) {image[i]=newunsignedchar[width];} bin->getImage(image);CIBrick::checkCollision函數(shù)的實(shí)現(xiàn)獲取當(dāng)前磚塊的狀態(tài)和特定點(diǎn)

orientation=getOrientation();posX=getPosX(); posY=getPosY();CIBrick::checkCollision函數(shù)的實(shí)現(xiàn)針對(duì)磚塊不同的狀態(tài)進(jìn)行檢查(以0狀態(tài)為例

if(orientation==0) {//磚塊碰到邊界

if( (posX<0)||(posX>width-1)|| (posY<1)||(posY+2>height-1)) return0;

//磚塊碰到其他固定磚塊

if((image[posY-1][posX]!=0)||(image[posY][posX]!=0)||(image[posY+1][posX]!=0)||(image[posY+2][posX]!=0))return0; }CIBrick::checkCollision函數(shù)的實(shí)現(xiàn)//I磚塊狀態(tài)1

if(orientation==1)

{

if((posX<2)||(posX+1>width-1)|| (posY<0)|| (posY>height-1)) return0; if((image[posY][posX-2]!=0)||(image[posY][posX-1]!=0)||(image[posY][posX]!=0)|| (image[posY][posX+1]!=0))return0; }CIBrick::checkCollision函數(shù)的實(shí)現(xiàn)

//“I”磚塊狀態(tài)2

if(orientation==2)

{

if((posX<0)||(posX>width-1)|| (posY<2)||(posY+1>height-1)) return0; if((image[posY-2][posX]!=0)|| (image[posY-1][posX]!=0)||(image[posY][posX]!=0)|| (image[posY+1][posX]!=0))return0; }CIBrick::checkCollision函數(shù)的實(shí)現(xiàn)//狀態(tài)3

if(orientation==3)

{

if((posX<1)||(posX+2>width-1)|| (posY<0)||(posY>height-1)) return0; if((image[posY][posX-1]!=0)|| (image[posY][posX]!=0)|| (image[posY][posX+1]!=0)|| (image[posY][posX+2]!=0))return0; }函數(shù)功能:設(shè)置游戲面板算法描述:獲取當(dāng)前磚塊的狀態(tài)、特定點(diǎn)和顏色針對(duì)磚塊不同的狀態(tài)進(jìn)行設(shè)置CIBrick::operator>>函數(shù)的實(shí)現(xiàn)獲取當(dāng)前磚塊的狀態(tài)、特定點(diǎn)和顏色voidCIBrick::operator>>(unsignedchar**binImage){intorientation; intposX; intposY; unsignedcharcolour; posX=getPosX(); posY=getPosY(); orientation=getOrientation(); colour=getColour();CIBrick::operator>>函數(shù)的實(shí)現(xiàn)針對(duì)磚塊不同的狀態(tài)進(jìn)行設(shè)置

if(orientation==0)//狀態(tài)0

{

binImage[posY-1][posX]=colour;binImage[posY][posX]=colour; binImage[posY+1][posX]=colour; binImage[posY+2][posX]=colour;} if(orientation==1)//狀態(tài)1

{

binImage[posY][posX-2]=colour;binImage[posY][posX-1]=colour; binImage[posY][posX]=colour; binImage[posY][posX+1]=colour;} CIBrick::operator>>函數(shù)的實(shí)現(xiàn)

if(orientation==2)//狀態(tài)2

{

binImage[posY-2][posX]=colour; binImage[posY-1][posX]=colour;binImage[posY][posX]=colo

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論