要素類和對(duì)象模版類的繼承教案資料_第1頁(yè)
要素類和對(duì)象模版類的繼承教案資料_第2頁(yè)
要素類和對(duì)象模版類的繼承教案資料_第3頁(yè)
要素類和對(duì)象模版類的繼承教案資料_第4頁(yè)
要素類和對(duì)象模版類的繼承教案資料_第5頁(yè)
已閱讀5頁(yè),還剩154頁(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)介

C++要素類和對(duì)象模版類的繼承預(yù)備知識(shí)——C++、類與對(duì)象C復(fù)習(xí)數(shù)據(jù)類型:在C語(yǔ)言中:基本類型和構(gòu)造類型基本類型:整型、浮點(diǎn)型、字符型、雙精度型

構(gòu)造類型:數(shù)組、結(jié)構(gòu)、聯(lián)合、指針、枚舉型數(shù)據(jù)對(duì)象:intn=3;inta[3];a[0]=-1;//整型數(shù)據(jù)對(duì)象charch=‘A’;//字符類型數(shù)據(jù)對(duì)象對(duì)象指針:int*p=&n,*q=a;C復(fù)習(xí)標(biāo)識(shí)符表達(dá)式語(yǔ)句:賦值句、條件句、循環(huán)句、函數(shù)調(diào)用(輸入輸出)函數(shù):返回值類型,函數(shù)名,參數(shù)列表遞歸:直接遞歸、間接遞歸C++介紹一.C++要素(BorlandC,VC)/*………*/

段注釋以/*開(kāi)始到*/結(jié)束

//行注釋到行末

2.注釋

例1:constintm=10;//定義m為常量值是104.

常量說(shuō)明const例2:constinta[]={1,3,5,7,9};//定義a是常量數(shù)組例3.int*constp;//常指針p指向一個(gè)固定的地址

例4.constint*q;//指針q指向常量可以在任何地方申明一個(gè)變量

例for(inti=0;i<5;i++)其作用域從申明地起到文末或函數(shù)末5.變量申明但不能while(inti)i++;intf(inta,intb=0);

調(diào)用f(5),即調(diào)用f(5,0);

6.函數(shù)缺省值參數(shù)缺省參數(shù)要寫(xiě)在參數(shù)表的右邊intf(inta,intb=0,intc=1);

inlineintsquare(intx){returnx*x;}

內(nèi)聯(lián)函數(shù)先編譯,效率高,速度快但只能有四五個(gè)語(yǔ)句,不能有循環(huán)語(yǔ)句,條件語(yǔ)句.7.內(nèi)聯(lián)函數(shù)

overloadabs;

intabs(int);

floatabs(float);

同名不同參數(shù)的函數(shù)可以重載系統(tǒng)會(huì)自動(dòng)選擇調(diào)用8.函數(shù)重載定義函數(shù)的變量參數(shù)

intf(int&x){intn=2*x++;returnn;}x為函數(shù)f的變量參數(shù)

調(diào)用實(shí)參的地址調(diào)用后實(shí)參的值可以改變函數(shù)需要兩個(gè)以上返回值時(shí),用變量參數(shù)9.引用操作符&例

int*p,*q;

p=newint(3);

q=newint[4];

為p分配一個(gè)整形地址(2字節(jié))*p==3為q分配4個(gè)整形地址(8個(gè)連續(xù)字節(jié))

deletep;//撤銷p的地址

delete[]q;//撤銷q的多個(gè)連續(xù)地址

10.動(dòng)態(tài)函數(shù)動(dòng)態(tài)變量

newdelete#include“iostream.h”

inta,b;charx,y;

cout<<“Enterx,y,a,b”<<endl;

cin>>x>>y;\\從鍵盤(pán)為變量x,y輸入數(shù)據(jù)

cin>>a>>b;\\從鍵盤(pán)為變量a,b輸入數(shù)據(jù)

cout<<“x=”<<x<<endl;

cout<<y<<a<<b<<endl;11.輸入輸出文件輸入輸出include“fstream.h”include“stdlib.h”voidmain(){ifstreaminfile(“datafile1.doc”);

if(!infile){cerr<<“Cannotopendatafile1.doc”<<endl;exit(1);}ofstreamoutfile(“datafile2.doc”);

if(!outfile){cerr<<“Cannotopendatafile2.doc”<<endl;exit(1);}

intn;stringname;while(infile>>n){infile>>name;outfile<<n<<“”<<name<<endl;}}一.C++要素(BorlandC3.1)1.文件擴(kuò)展名*.cpp2.注釋/*………*/段注釋

//行注釋到行末3.續(xù)行\(zhòng)常量說(shuō)明const5.變量申明可以在任何地方申明一個(gè)變量6.函數(shù)缺省值參數(shù)

int

f(inta,intb=0);7.內(nèi)聯(lián)函數(shù)8.重載overload引用操作符&10.動(dòng)態(tài)函數(shù)動(dòng)態(tài)變量newDelete11輸入輸出

二.

類和對(duì)象

1.類的定義

class類名稱{private:數(shù)據(jù)成員;成員函數(shù);protected:數(shù)據(jù)成員;成員函數(shù);public:數(shù)據(jù)成員; 成員函數(shù);};//類定義結(jié)束必須有分號(hào)“;”class

是保留字,

作用與struct

相同

定義一個(gè)結(jié)構(gòu)也叫類。

private(私有),缺省

protected(保護(hù))

,

public(公有)都是訪問(wèn)限制例計(jì)數(shù)器類

存儲(chǔ)于文件“count.h”中

classcounter{private://私有成員

unsignedintvalue;//數(shù)據(jù)成員

public://公有成員counter(){value=0;}//無(wú)參構(gòu)造函數(shù)counter(intx){if(x>0)value=x;elsevalue=0;}//有參構(gòu)造函數(shù)

voidincrement(){if(value<65535)value++;}

voiddecrement(){if(value>0)value--;}

unsignedaccess_value(){returnvalue;}};counterc1,c2;//語(yǔ)句1

counterc3(5);//語(yǔ)句2語(yǔ)句1定義counter類的對(duì)象c1,c2,即實(shí)際變量(實(shí)例)。對(duì)象定義時(shí)必須為數(shù)據(jù)成員賦初值即初始化。初始化由類中的構(gòu)造函數(shù)自動(dòng)完成。語(yǔ)句1自動(dòng)調(diào)用counter類中無(wú)參構(gòu)造函數(shù),使c1.value=c2.value=0。

語(yǔ)句2定義對(duì)象c3,自動(dòng)調(diào)用有參構(gòu)造函數(shù)使c3.value=5.2.對(duì)象的定義object注意:不能使用c1.value為它賦值;因?yàn)関alue在counter類中是私有成員不可見(jiàn),只能用成員函數(shù)來(lái)調(diào)用。對(duì)象不能直接調(diào)用私有成員,只能通過(guò)公有成員函數(shù)來(lái)調(diào)用私有成員對(duì)象調(diào)用成員函數(shù),叫發(fā)一個(gè)消息為c1發(fā)消息:c1.increment();//計(jì)數(shù)器自動(dòng)加1c1.decrement();//計(jì)數(shù)器自動(dòng)減1例計(jì)數(shù)器測(cè)試程序#include“iostream.h”

#include“count.h”voidmain(){counterc1,c2;

for(inti=1;i<=8;i++){c1.increment();cout<<“\nc1=”<<c1.access_value();c2.increment();}cout<<“c2=”<<c2.access_value();

for(i=1;i<=5;i++){c2.decrement();cout<<“\nc2=”<<c2.access_value();c1.decrement();}cout<<“c1=”<<c1.access_value();}測(cè)試結(jié)果c1=1c1=2c1=3c1=4c1=5c1=6c1=7c1=8c2=8c2=7c2=6c2=5c2=4c2=3c1=3圓的類classCircle{floatradius;

public:Circle(floatr=0):radius(r){}//構(gòu)造函數(shù)floatGetRadius();floatCircleCircum();floatCircleArea();};成員函數(shù)類外定義Circle::Circle(floatr)//構(gòu)造函數(shù){radius=r;}floatCircle::GetRadius(){returnradius;}floatCircle::CircleCircum(){return2*3.14.6*radius;}floatCircle::CircleArea(){return3.1416*radius*radius;}圓類的測(cè)試#include“iostream.h”

#include“circle.h”voidmain(){Circlea(3),b(2);cout<<“CircumofCirclea=”<<a.CircleCircum()<<endl;cout<<“AreaofCircleb=”<<b.CircleArea()<<endl;}長(zhǎng)方形類classRectangle{floatx,y;public:Rectangle(floata=0,floatb=0):x(a),y(b){}floatRecCircum(){return2*(x+y);}floatRecArea(){returnx*y;}};a.對(duì)象指針如同定義一個(gè)對(duì)象一樣,用類名可以申明一個(gè)對(duì)象指針。例counter*p,*q;申明counter類的指針,指針沒(méi)有初始化,調(diào)用指針必須先分配內(nèi)存,或指向一個(gè)變量的地址,否則出嚴(yán)重錯(cuò)誤,甚至死機(jī)。3.對(duì)象指針和對(duì)象數(shù)組

(1)p=newcounter(3);分配一個(gè)整形數(shù)據(jù)內(nèi)存,這時(shí)系統(tǒng)自動(dòng)調(diào)用有參構(gòu)造函數(shù)初始化*p的value=3;(2)q=newcounter[3];分配三個(gè)連續(xù)整形數(shù)據(jù)內(nèi)存,這時(shí)系統(tǒng)自動(dòng)調(diào)用無(wú)參構(gòu)造函數(shù)初始化q,q+1,q+2的value都是0。如果類中沒(méi)有無(wú)參構(gòu)造函數(shù),語(yǔ)句(2)出錯(cuò)。

確定地址后的對(duì)象指針可以調(diào)用類中公有數(shù)據(jù)及公有函數(shù)。p→increment();(q+1)→decrement();(*p).decrement();

(*p).decrement()中的括號(hào)不能省略,因?yàn)檫\(yùn)算符.的優(yōu)先級(jí)高于*;

對(duì)象指針用畢,要予以撤銷,釋放內(nèi)存,deletep;delete[]q;

撤銷后的指針可以再用,只要重新分配內(nèi)存或指向一個(gè)內(nèi)存。b.對(duì)象數(shù)組

如果類中有無(wú)參構(gòu)造函數(shù),可以定義對(duì)象數(shù)組(3)counterc[3];這時(shí)系統(tǒng)自動(dòng)調(diào)用無(wú)參構(gòu)造函數(shù)初始化c[0],c[1],c[2]的value都是0。如果類中沒(méi)有無(wú)參構(gòu)造函數(shù),語(yǔ)句(3)出錯(cuò)。a.一個(gè)類中的數(shù)據(jù)成員不可以初始化,例classA{intvalue=0;\\出錯(cuò).......};b.另一個(gè)類的對(duì)象可以做本類的數(shù)據(jù)成員,但要先定義后作成員。只先申明不行。本類對(duì)象不可以做自己的數(shù)據(jù)成員。c.指向本類或另一類對(duì)象的指針,或引用可以作本類的數(shù)據(jù)成員。只要先申明就可以。4.類的數(shù)據(jù)成員d.公有成員和私有成員的先后次序可以交換??梢园阉接谐蓡T寫(xiě)在類的前部,也可以寫(xiě)在后部。e.本類對(duì)象可以調(diào)用本類公有數(shù)據(jù)或公有函數(shù),不能調(diào)用私有數(shù)據(jù)和私有成員。例classA;classB

{A*p;//合法A&q;//合法B*r;//合法Aa;//出錯(cuò)Bb;//出錯(cuò)

};長(zhǎng)方形和圓的類classRecCircle{RectangleRec;

CircleCir;public:

RecCircle(floata,floatb,floatc):Rec(a,b),Cir(c){}floatCircum(){returnRec.RecCircum()+Cir.CircleCircum();}floatArea(){returnRec.RecArea()+Cir.CircleArea();};成員函數(shù)也叫類所具有的方法或操作。函數(shù)頭叫方法的界面,也叫消息模式。函數(shù)可以重載(要求參數(shù)不同)不必用overload??梢灶悆?nèi)申明類外定義,類內(nèi)定義時(shí)不用inline即內(nèi)聯(lián)。成員函數(shù)可以調(diào)用本類數(shù)據(jù)成員,無(wú)論公有或私有。對(duì)象調(diào)用公有成員函數(shù)叫做發(fā)一個(gè)消息。5.類的成員函數(shù)構(gòu)造函數(shù)可以重載,帶缺省參數(shù)時(shí),要特別注意避免二義性。

構(gòu)造函數(shù)一般都是公有函數(shù)。只有私有構(gòu)造函數(shù)的類不能定義對(duì)象。只有本類對(duì)象或本類成員函數(shù)才能調(diào)用成員函數(shù)。

成員函數(shù)必須由對(duì)象調(diào)用,調(diào)用成員函數(shù)的對(duì)象可以看作一個(gè)隱含的參數(shù),這是一個(gè)指針參數(shù),用this表示。this指針指向調(diào)用成員函數(shù)的對(duì)象。例Circle::CircleArea(){return3.1416*radius*radius;}//其中radius實(shí)際意義是this→radius.Circlea(3.4);cout<<a.CircleArea();//this指針指向a6.This指針

this指針counter::increament(){if(value<65535)value++;}//隱含參數(shù)this指針,this->value

counterc;c.increament();//實(shí)際參數(shù)是c,this指向c

與類名同名的成員函數(shù)叫構(gòu)造函數(shù),構(gòu)造函數(shù)沒(méi)有返回類型。構(gòu)造函數(shù)的作用是自動(dòng)為對(duì)象初始化。對(duì)象不能調(diào)用構(gòu)造函數(shù)。如果一個(gè)類中沒(méi)有構(gòu)造函數(shù),系統(tǒng)會(huì)自動(dòng)生成一個(gè)無(wú)參構(gòu)造函數(shù)。如果一個(gè)類中有有參構(gòu)造函數(shù),系統(tǒng)就不再自動(dòng)生成無(wú)參構(gòu)造函數(shù),這時(shí),用類定義對(duì)象數(shù)組或?qū)ο笾羔樁伎赡艹鲥e(cuò)。7.構(gòu)造函數(shù)一個(gè)類中如果沒(méi)有構(gòu)造函數(shù),系統(tǒng)會(huì)自動(dòng)生成

一個(gè)無(wú)參構(gòu)造函數(shù),使所有的數(shù)據(jù)成員都置0。

一個(gè)類中如果有有參構(gòu)造函數(shù),系統(tǒng)就不再生

成無(wú)參構(gòu)造函數(shù)。例如RecCirle類中,就沒(méi)有無(wú)參構(gòu)造函數(shù)。

這時(shí)要小心,下面一個(gè)語(yǔ)句會(huì)出錯(cuò)

RecCircled;//出錯(cuò)無(wú)法初始化

RecCircles[3];//出錯(cuò)無(wú)法初始化正確的定義形式是

RecCircled(2.0,3.5,4);8.拷貝構(gòu)造函數(shù)構(gòu)造函數(shù)的參數(shù)不能是本類對(duì)象,但可以是本類對(duì)象的引用,這樣的構(gòu)造函數(shù)叫拷貝構(gòu)造函數(shù)。classCircle{floatradius;

public:Circle(floatr=0):radius(r){}//構(gòu)造函數(shù)Circle(Circle&c){radius=c.radius;}//拷貝構(gòu)造函數(shù)floatGetRadius();floatCircleCircum();floatCircleArea();};

1)用已有對(duì)象定義新的對(duì)象。Circlea(2);Circleb(a);

第二個(gè)語(yǔ)句就是利用拷貝構(gòu)造函數(shù)定義賦數(shù)對(duì)象b,b的半徑等于a的半徑。

拷貝構(gòu)造函數(shù)的作用:拷貝構(gòu)造函數(shù)的作用:2)本類對(duì)象作函數(shù)的參數(shù)時(shí),要用拷貝構(gòu)造函數(shù)傳值。3)一個(gè)函數(shù)的返回值是本類對(duì)象時(shí),要用拷貝構(gòu)造函數(shù)賦值。CircleFun(Circlet){returnCircl(2*t.radius);}如果類中沒(méi)有拷貝構(gòu)造函數(shù)系統(tǒng)會(huì)自動(dòng)生成一個(gè)。如果類中有指針成員,就必須專門(mén)定義拷貝構(gòu)造函數(shù),否則可能出錯(cuò)。例classA

{int*p;pubic:A(){p=newint(0);}A(A&s){p=newint(*s.p);};

以~開(kāi)頭與類名同名的成員函數(shù)稱為析構(gòu)函數(shù)。析構(gòu)函數(shù)無(wú)參無(wú)返回值。例classA

{....

~A();....};9.析構(gòu)函數(shù)析構(gòu)函數(shù)的作用:當(dāng)本類的一個(gè)對(duì)象用完后,系統(tǒng)自動(dòng)調(diào)用析構(gòu)函數(shù),撤銷內(nèi)存。這種情況常在一個(gè)函數(shù)中發(fā)生,一個(gè)對(duì)象在函數(shù)中作局部變?cè)瘮?shù)用畢后,局部變?cè)В鰳?gòu)函數(shù)就會(huì)自動(dòng)起作用。類中沒(méi)有析構(gòu)函數(shù)時(shí)系統(tǒng)會(huì)自動(dòng)生成一個(gè)析構(gòu)函數(shù)。當(dāng)類中含有指針對(duì)象時(shí),應(yīng)當(dāng)定義一個(gè)析構(gòu)函數(shù),以免指針指向的內(nèi)存掛起失。classA{int*p;public:A(){p=newint;}....~A(){deletep;}....};注意類外對(duì)象指針用new分配的內(nèi)存,不會(huì)調(diào)用析構(gòu)函數(shù),而要用delete釋放。例坐標(biāo)點(diǎn)point類classPoint{public:Point(int,int);//構(gòu)造函數(shù)Point(Point&);//拷貝構(gòu)造函數(shù)//~Point();析構(gòu)函數(shù)

intget_x();//取橫坐標(biāo)

intget_y();//取縱坐標(biāo)Pointoperator+(Point&);//重載+Pointoperator*(int);//重載*Pointoperator-();//一元函數(shù)-重載

Point&operator=(constPoint&);//賦值函數(shù)

private://私有數(shù)據(jù)

intx,y;friendistream&

operator>>(istream&,Point&);

//友元輸入函數(shù)重載>>friendostream&

operator<<(ostream&,Point&);//友元輸出函數(shù)重載<<

};Point::Point(inta,intb){x=a;y=b;}Point::Point(Point&p){x=p.get_x();y=p.get_y();}intPoint::get_x(){returnx;}intPoint::get_y(){returny;}PointPoint::operator+(Point&p){x=x+p.x;y=y+p.y;return*this;}PointPoint::operator*(intn){x=n*x;y=n*y;return*this;}Point

Point::operator-(){x=-x;y=-y;return*this;}Point&

Point::operator=(constPoint&p){x=p.x;y=p.y;return*this;}istream&

operator>>(istream&istr,Point&p){istr>>p.x>>p.y;returnistr;}ostream&

operator<<(ostream&ostr,Point&p){ostr<<“(”<<p.x<<“,”<<p.y<<“)”<<endl;

returnostr;}除了少數(shù)幾個(gè)操作符,如“,”,“::”,“?:”,“{}”之外,其余都可以重載。二元運(yùn)算在成員函數(shù)看來(lái),只有一個(gè)參數(shù),另一個(gè)是this指針。例PointPoint::operator+(Point&c);二元運(yùn)算+在復(fù)數(shù)類中重載,變成只有一個(gè)參數(shù)。11.運(yùn)算符(操作符)重載

Point

a1(1,2),a2(2,-1);a1=a1+a2;表達(dá)式a1=a1+a2中對(duì)象a1調(diào)用運(yùn)算+,實(shí)際參數(shù)為a2,返回值還是Point類型,還可以再調(diào)用運(yùn)算符+,因此表達(dá)式a1+a2+a1有意義。

在classPoint

中重載賦值函數(shù)

classPoint

{....

Point&operator=(constPoint&c){x=c.x;y=c.y;return*this;}......};12.賦值函數(shù)重載

賦值函數(shù)的作用是把一個(gè)對(duì)象的所有內(nèi)容,賦予另一個(gè)對(duì)象.

c1=c2;c1=c1+c2;類中沒(méi)有賦值函數(shù)時(shí)系統(tǒng)會(huì)自動(dòng)生成一個(gè)賦值函數(shù)。當(dāng)類中含有指針對(duì)象時(shí),應(yīng)當(dāng)定義一個(gè)賦值函數(shù),以保證值把內(nèi)容賦值,而不是把地址賦值造成析構(gòu)函數(shù)調(diào)用時(shí)出錯(cuò)。例classA

{int*p;public:

.....A&operator=(A&a)

{if(this=&a)return*this;else*p=*a.p;return*this;}.....};

一元運(yùn)算作成員函數(shù)重載時(shí)變成零元函數(shù)。PointPoint::operator-(){x=-x;y=-y;returnreturn*this;}調(diào)用寫(xiě)成-c1或c1=-c2;13.一元運(yùn)算重載10.友元友元有權(quán)訪問(wèn)類內(nèi)所有成員,不論公有,保護(hù),還是私有成員。友元沒(méi)有this指針,必要時(shí)可以用類對(duì)象的引用作參數(shù)。友元可以是一個(gè)類,這時(shí)友元類中所有成員函數(shù)都是友元。友元不傳遞,不對(duì)稱,不繼承。友元沒(méi)有this指針,比成員函數(shù)多一個(gè)參數(shù)。istream&

operator>>(istream&istr,Point&p){istr>>p.x>>p.y;returnistr;}ostream&

operator<<(ostream&ostr,Point&p){ostr<<“(”<<p.x<<“,”<<p.y<<“)”<<endl;

returnostr;}友元不是類的成員,不用類名域Point::operator函數(shù)在類內(nèi)申明類外定義

例日期類保存于“date.h”中

classdate{intmonth,day,year;//私有數(shù)據(jù)

public:date(int,int,int);//有參構(gòu)造函數(shù)

voidnext();

voidprint();}today;

inlinedate::date(inta,intb,intc){month=a;day=b;year=c;}voiddate::print(){cout<<month<<“/”<<day;cout<<“/”<<year<<endl;}voiddate::next(){switchmonth

case1:case3:case

5:case

7:case

8:case10:{if(day<31)day++;

else{month++;day=1;}}break;

case4:case6:case

9:case

11:{if(day<30)day++;

else{month++;day=1;}}break;

case

12:{if(day<31)day++;

else{year++;month=1;day=1;}}break;

case

2:case2:if((year%4==0)&&year%400!=0)

||(year%400==0)){if(day<29)day++;

else{month++;day=1;}}

else{if(day<28)day++;

else{month++;day=1;}}}例date類測(cè)試程序

#include“iostream.h”

#include“date.h”

void

main(){datetoday(2,13,2001);//定義對(duì)象datemyBirthday(6,24,1983);//定義對(duì)象today.next();//對(duì)象調(diào)用操作today.print();myBirthday.print();}測(cè)試結(jié)果2/14/20016/24/1983三、模版(template)

通用數(shù)據(jù)類

模版函數(shù)通用函數(shù)2.

類模版通用數(shù)據(jù)類型模版函數(shù)

通用函數(shù)

幾個(gè)形式上完全相同的函數(shù),只有

參數(shù)類型和返回值類型不同,可以寫(xiě)成通用函數(shù),也叫模版函數(shù)。例.intmax(inta,intb)

{returna>b?a:b;}float

max(floata,floatb){returna>b?a:b;}

char

max(chara,charb){returna>b?a:b;}可以統(tǒng)一寫(xiě)成一個(gè)模版函數(shù)template<classT>Tmax(Ta,Tb){returna>b?a:b;}這里T是類型參數(shù)可以用任意一個(gè)標(biāo)識(shí)符模版函數(shù)的調(diào)用對(duì)不同的參數(shù)都可以調(diào)用函數(shù)maxinta,b;charx,y;a=3;b=5;x='A';y='b';a=max(a,b);\\有意義x=max(x,y);\\有意義參數(shù)可以用字符串,甚至復(fù)雜的結(jié)構(gòu)變量,對(duì)象,只要事先定義大小關(guān)系。2.類模版通用數(shù)據(jù)類型//array.h例.通用數(shù)組抽象數(shù)組類型

template<classT>

classArray{T*alist;//指針數(shù)據(jù)表示一個(gè)數(shù)組

intsize;//表示數(shù)組長(zhǎng)度

public:

Array(ints=50)//構(gòu)造函數(shù)

Array(constArray<T>&X);//拷貝構(gòu)造函數(shù)~Array(){delete[]element;}//析構(gòu)函數(shù)

Array<T>&operator=(constArray<T>&X);//賦值函數(shù)重載

T&operator[](inti);//一元運(yùn)算[]重載下標(biāo)函數(shù)

operatorT*()const;

//強(qiáng)制類型轉(zhuǎn)換,將當(dāng)前

//對(duì)象變成指向它的首地址的指針,

intArraySize()const;//取數(shù)組長(zhǎng)

voidResize(intsz);//數(shù)組長(zhǎng)重定義

friendostream&operator<<(ostream&,constArray<T>&);

//輸出操作重載};template<classT>

classArray{T*alist;//指針數(shù)據(jù)表示一個(gè)數(shù)組

intsize;//表示數(shù)組長(zhǎng)度

public:

Array(ints=50)//構(gòu)造函數(shù)

Array(constArray<T>&X);//拷貝構(gòu)造函數(shù)~Array(){delete[]element;}//析構(gòu)函數(shù)Array<T>&operator=(constArray<T>&X);

//賦值函數(shù)重載

T&operator[](inti);//一元運(yùn)算[]重載//下標(biāo)函數(shù)

operatorT*()const;

//強(qiáng)制類型轉(zhuǎn)換,將當(dāng)前//對(duì)象變成指向它的首地址的指針,

intArraySize()const;//取數(shù)組長(zhǎng)

voidResize(intsz);//數(shù)組長(zhǎng)重定義

friendostream&operator<<

(ostream&,constArray<T>&);//輸出操作重載};//構(gòu)造函數(shù)

template<classT>Array<T>::Array(intsz){size=sz;alist=new

T[size];

if(alist==0){cout<<“內(nèi)存不夠”;

return;}}//析構(gòu)函數(shù)destructortemplate<class

T>Array<T>::~Array(void){

delete[]alist;}//copyconstructor拷貝構(gòu)造函數(shù)template<class

T>Array<T>::Array(constArray<T>&X){intn=X.size;//取對(duì)象X的長(zhǎng)度作為當(dāng)前對(duì)象的長(zhǎng)size=n;alist=newT[n];//allocatedynamicarray

if(alist==0)//作正確性檢查{cout<<“內(nèi)存不夠”;return;}

//copyarrayitemsfromXtocurrentobject

T*srcptr=X.alist;//addressatstartofX.alist

T*destptr=alist;//addressatstartofalist

while(n--)//copylist*destptr++=*srcptr++;}template<classT>//賦值函數(shù)重載Array<T>&Array<T>::operator=(constArray<T>&X){

intn=X.size;//取X的長(zhǎng)度

if(size!=n)//若長(zhǎng)度不同,重新分配內(nèi)存

{delete[]alist;//destroyoriginalmemoryalist=newT[n];//allocateanewarrayif(alist==0){cout<<“內(nèi)存不夠”;return;}size=n;}

//將對(duì)象X的元素逐個(gè)拷貝到當(dāng)前對(duì)象//copyarrayitemsfromXtocurrentobject

T*destptr=alist;

T*srcptr=X.alist;

while(n--)*destptr++=*srcptr++;//返回當(dāng)前對(duì)象的值//returnreferencetothecurrentobject

return*this;}//一元運(yùn)算[]重載下標(biāo)函數(shù)

//overloadedindexoperator

template<classT>T&Array<T>::operator[](intn){

//doarrayboundscheckingif(n<0||n>size-1){cout<<"下標(biāo)超界”;return;}

//returntheelementfromtheprivatearraylist

returnalist[n];}

//強(qiáng)制類型轉(zhuǎn)換,將當(dāng)前對(duì)象

//變成指向它的首地址的指針,

//pointerconversionoperatortemplate<classT>Array<T>::operatorT*()const{//returnaddressofprivatearrayinthe//currentobject

returnalist;}//取當(dāng)前對(duì)象的長(zhǎng)template<class

T>intArray<T>::ListSize()const{

returnsize;}//改變當(dāng)前對(duì)象的長(zhǎng)度

//resizeoperatortemplate<class

T>voidArray<T>::Resize(intsz){//testnewsizeparameter;terminateifsize<=0

if(sz<=0){cout<<“長(zhǎng)度不能小于等于0”;return;}

//nothingtodoifsizehasn'tchanged

if(sz==size)return;

//requestnewmemoryandverifysystemresponse

T*newlist=newT[sz];if(newlist==0){cout<<“內(nèi)存不夠”;return;}

intn=(sz<=size)?sz:size;//n取較小的一個(gè)

//copynarrayitemsfromoldtonewmemory

T*srcptr=alist;//addressatstartofalist

T*destptr=newlist;//addressatstartofnewlist

while(n--)//copylist*destptr++=*srcptr++;

delete[]alist;//deleteoldlist

//resetalisttopointatnewlistandupdatethesizealist=newlist;size=sz;}ostream&operator<<(ostream&out,constArray<T>&a){for(inti=0;i<a.size;i++)

out<<a.alist[i]<<‘’;

out<<endl;}//通用數(shù)組類的測(cè)試#include<iostream.h>#include

"array.h"voidmain(void){Array<int>a(20);//定義長(zhǎng)為0的整數(shù)數(shù)組

for(inti=0;i<20;i++)a[i]=i+1;//下標(biāo)函數(shù)返回值是類型T的引用//可以寫(xiě)在表達(dá)式的左邊

Array<int>b(a),c=a;//用拷貝構(gòu)造函數(shù),//賦值函數(shù)建立新對(duì)象

cout<<a<<b<<c;}還可以定義字符數(shù)組,記錄類型數(shù)組,復(fù)數(shù)類的數(shù)組,二維數(shù)組,三維數(shù)組等等,方法與C語(yǔ)言相同。#include<iostream.h>#include"array.h"#include“complex.h"voidmain(void){Array<complex>a(20);complexs(1,2);for(inti=0;i<20;i++)

a[i]=a[i]+s;Array<complex>b(a),c=a;cout<<a<<b<<c;}3.多于一個(gè)參數(shù)的模版模版可以有不止一個(gè)參數(shù),可以是某個(gè)簡(jiǎn)單類型參數(shù),也可以是通用參數(shù)。例

template<classT,classS>

classNode

{Node<T,S>*previous,*next;

T*T_data;

S*S_data;

Public:

Node(Node<T,S>*,Node<T,S>*,T*,S*);~Node();}template<classT,classS>Node<T,S>::Node(Node<T,S>*p,

Node<T,S>*q,T*t,S*s)

{previous=p;next=q;T_data=t;S_data=s;}template<classT,classS>Node<T,S>::~Node()

{deleteT_data;deleteS_data;}4.類模版可以嵌套

template<classT,classS>classList{Node<T,S>*head,*current;public:List();voidInsert(T*,S*);voidRemove(T*,

S*);

~List();}四、類的繼承簡(jiǎn)單繼承多重繼承多態(tài)性和虛函數(shù)簡(jiǎn)單繼承

1.派生類的定義2.基類成員的引用和訪問(wèn)的規(guī)則3.導(dǎo)出類的構(gòu)造函數(shù)4.覆蓋作用域分辨5.派生類的類型轉(zhuǎn)換6.導(dǎo)出類的指針簡(jiǎn)單繼承從一個(gè)類可以派生出新的類——派生類或?qū)С鲱?,也叫子?原來(lái)的類叫基類也叫父類.1.派生類的定義形式class新類名:public基類名//公有繼承{·········};class新類名:private基類名//私有繼承

{·········};

//缺省為私有繼承,//基類是struct類時(shí)缺省是公有繼承基類中的成員自動(dòng)成為導(dǎo)出類的成員?;愊拗圃~:public和private指明基類成員在導(dǎo)出類中的訪問(wèn)限制classAclassB:publicAclassC:publicB例:classroadVehicle{intwheels,passengers;public:

roadVehicle(int,int); voidSetWheels(intnum); voidSetPassengers(intnum); intGetWheels(void); intGetPassengers(void);voidprint(){cout<<“\nwheels=”<<wheels<<“\nPassengers=”<<passengers;}};

classtruck:public

roadVehicle{intcargo;public:

truck(int,int,int);voidSetCargo(intsize);intGetCargo(void);voidShow(void);voidprint();};Truck類有三個(gè)數(shù)據(jù)成員:wheels,passengerscargo.有9個(gè)成員函數(shù)1。構(gòu)造函數(shù)和析構(gòu)函數(shù)2。重載的操作符和賦值符3。友元不繼承的部分基類中同名的成員被派生類中相應(yīng)的名字覆蓋2.基類成員的引用和訪問(wèn)的規(guī)則classAclassB:publicAclassC:publicBprivate不可見(jiàn)不可見(jiàn)protectedprotectedprotectedpublicpublicpublicclassAclassB:privateAclassC:privateBprivate不可見(jiàn)不可見(jiàn)protectedprivate不可見(jiàn)publicprivate不可見(jiàn)保護(hù)成員protected數(shù)據(jù)在基類中同private公有基類的保護(hù)成員和公有成員是導(dǎo)出類的保護(hù)和公有成員私有基類的保護(hù)成員和公有成員是導(dǎo)出類私有成員基類的私有成員在導(dǎo)出類中不可見(jiàn)只能通過(guò)基類的公有成員函數(shù)調(diào)用例voidtruck::print(void){cout<<“\nwheels=”<<wheels

//出錯(cuò)

<<“\npassengers=”<<passengers

//出錯(cuò)<<“\ncargo=”<<cargo;}應(yīng)改為voidtruck::print(void){roadVehicle::print();cout<<“\ncargo=”<<cargo;}3.導(dǎo)出類的構(gòu)造函數(shù)派生類不繼承構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)必須包含基類構(gòu)造函數(shù)的信息要為基類構(gòu)造函數(shù)提供初始化參數(shù)classtruck的構(gòu)造函數(shù):truck::truck(inta,intb,intc):roadVahicle(a,b)如果roadVehicle類中roadVehicle::roadVehicle(intx,inty){wheels=x;passengers=y;}則truck類中truck::truck(inta,intb,intc):roadVehicle(a,b){cargo=c;}

注意:導(dǎo)出類的構(gòu)造函數(shù)中未寫(xiě)明基類構(gòu)造函數(shù)基類構(gòu)造函數(shù)的參數(shù)無(wú)法傳遞,這時(shí)導(dǎo)出類自動(dòng)調(diào)用基類的無(wú)參構(gòu)造函數(shù),如果基類沒(méi)有無(wú)參構(gòu)造函數(shù),就會(huì)出錯(cuò)。如果派生類中還有基類的對(duì)象成員classtruck:publicroadVehicle{intcargo;roadVehiclea;public:

truck(int,int,int,int,int);

truck(intx):roadVehicle(x,x+1),a(x,x){cargo=x;}voidSetCargo(intsize);intGetCargo(void);voidShow(void);voidprint();};例truck類的構(gòu)造函數(shù)truck::truck(inta1,inta2,intb1,intb2,intc):roadVehicle(a1,a2),a(b1,b2){cargo=c;}基類的構(gòu)造函數(shù)由基類名標(biāo)出對(duì)象成員的構(gòu)造函數(shù)由對(duì)象名標(biāo)出構(gòu)造函數(shù)的調(diào)用順序

先基類再導(dǎo)出類析構(gòu)函數(shù)相反4.覆蓋作用域分辨基類中同名的成員被派生類中相應(yīng)的名字覆蓋例classA{······public:······intfun(){return1;}}classB:publicA{······public:······intfun()//覆蓋A中同名元{return2;}}Aa;Bb;inti=a.fun();//i=1intj=b.fun();//j=2

i=b.A::fun();//i=1作用域分辨classB:publicA{······public:······intfun(){return2;}intf(){returnA::fun();}}Bb;inti=b.fun();//i=2intj=b.f();//i=1例truck類中的print函數(shù)voidtruck::print(void){roadVehicle::print();cout<<“\ncargo=”<<cargo;}truckt(4,3,4);

t.print();

輸出:wheels=4passengers=3cargo=45.派生類的類型轉(zhuǎn)換classA{······};classB:publicA{······};B是A的派生類,B是A的超集可以將類B的對(duì)象自動(dòng)轉(zhuǎn)換為A類對(duì)象,反之不成立.Aa;Bb;A*ap=newA;B*bp=newB;a=b;//正確ap=bp;//正確b=a;//錯(cuò)誤bp=ap;//錯(cuò)誤用戶定義類型轉(zhuǎn)換類型轉(zhuǎn)換函數(shù)重載X::operatorT();X是原定義類型,T是轉(zhuǎn)換后類型。不帶參數(shù),沒(méi)有返回類型。T就是返回類型。例String::operatorchar*(void){returnstr;}operatorchar*(void)是String類的成員函數(shù)String類對(duì)象可以作char*字符串類型使用。X::operatorT();X類對(duì)象可以作T類型使用Xs;Ta=s;//隱式轉(zhuǎn)換用于初始化Tfun(Tt);

a=fun(s);//隱式轉(zhuǎn)換用于函數(shù)參數(shù)Xf(Xt);

a=f(s);//隱式轉(zhuǎn)換用于函數(shù)返回值

隱式類型轉(zhuǎn)換的規(guī)則:用于初始化,函數(shù)參數(shù),函數(shù)返回值1.標(biāo)準(zhǔn)轉(zhuǎn)換優(yōu)先(轉(zhuǎn)換成標(biāo)準(zhǔn)類型)。2.不允許轉(zhuǎn)換再轉(zhuǎn)換3.必須唯一確定,不能有二義性。不能用隱式類型轉(zhuǎn)換時(shí)用強(qiáng)制類型轉(zhuǎn)換a=T(s);//顯式轉(zhuǎn)換強(qiáng)制類型轉(zhuǎn)換6.導(dǎo)出類的指針1公有基類指向?qū)С鲱悓?duì)象的指針可以隱式轉(zhuǎn)換為指向基類對(duì)象的指針?lè)粗怀闪?/p>

classA{······};classB:publicA{······};A*ap=newA;B*bp=newB;ap=bp;//正確bp=ap;//錯(cuò)誤bp=(B*)ap;//正確,//顯式轉(zhuǎn)換2.私有基類——不能隱式轉(zhuǎn)換多重繼承classA;classB;classC:publicA,publicB{······};1.多重繼承的定義由多個(gè)基類派生出一個(gè)類每個(gè)基類都應(yīng)有自己的存定符A,B的成員都自動(dòng)成為C的成員,存取權(quán)限同單繼承classAclassBclassC2.構(gòu)造函數(shù)導(dǎo)出類的構(gòu)造函數(shù)要為基類提供初始化參數(shù)方法與單繼承相同。調(diào)用時(shí)先基類再導(dǎo)出類。基類的次序從左到右。C::C(inta,intb,intc):A(a),B(b){······}3.二義性和覆蓋兩個(gè)基類中有同名成員都被繼承。導(dǎo)出類對(duì)象調(diào)用時(shí)出現(xiàn)二義性,要用類名域加以區(qū)別。也可以在導(dǎo)出類中定義一個(gè)同名成員加以覆蓋,消除二義性。classAclassBclassCclassA{public:voidf();};classB{public:voidf();};classC:publicA,publicB{public:······};Cc;c.f();//二義性A的f,B的f?c.A::f();//合法c.B::f();//合法classA{public:voidf();};classB{public:voidf();};classC:publicA,publicB{public:······};Cc;c.f();

//二義性A的f,B的f?c.A::f();//合法c.B::f();

//合法voidf(){A::f();B::f();}};//合法同時(shí)執(zhí)行兩個(gè)f4.虛基類一個(gè)基類被派生出兩個(gè)以上導(dǎo)出類,這兩個(gè)導(dǎo)出類再生成一個(gè)多重導(dǎo)出類.在導(dǎo)出類D中,A的一個(gè)元素通過(guò)兩個(gè)途徑被繼承了兩次。這種情況叫雙重繼承。classBclassCclassDclassA虛基類

虛基類定義可以避免雙重繼承classBclassCclassDclassAclassA;classB:virtualpublicA;classC:virtualpublicA;ClassD:publicB,publicC;這樣定義的D類中A的成員只繼承一次,可以直接訪問(wèn)A的成員,也可以用任意路徑訪問(wèn)。注意基類的所有直接導(dǎo)出類中都要用virtual聲明為虛基類,否則仍然是多重繼承。classB:virtualAclassC:virtualAclassDclassA構(gòu)造函數(shù)的調(diào)用次序先虛基類(依聲明次序從左到右)后非虛基類(依聲明次序)編制學(xué)校全體教職員工人員卡在校人員學(xué)生教師職工

本科生研究生在職研究生兼職教師要求:編號(hào),姓名,性別,出生日期,學(xué)生:系,級(jí),三門(mén)主課成績(jī),研究生:專業(yè),導(dǎo)師教師:系,專業(yè),職稱,職工:部門(mén),職務(wù)輸入:10個(gè)代表人物,格式化打印多態(tài)性和虛函數(shù)1.多態(tài)性不同的對(duì)象調(diào)用同一個(gè)函數(shù)導(dǎo)致不同的操作稱為多態(tài)性運(yùn)算符重載和函數(shù)重載是最簡(jiǎn)單的多態(tài)性1.動(dòng)態(tài)聯(lián)編程序在編譯時(shí)決定由某對(duì)象對(duì)實(shí)例發(fā)出的消息,翻譯并完成所要求的操作,叫前期裝配,或早聯(lián)編(earlybinding),也叫靜態(tài)聯(lián)編。程序在編譯時(shí)不確定由某對(duì)象對(duì)實(shí)例發(fā)出的消息,而是在運(yùn)行過(guò)程中確定由哪個(gè)對(duì)象實(shí)例發(fā)出的消息,翻譯并完成所要求的操作,叫后期裝配,或后聯(lián)編(laterbinding),也叫動(dòng)態(tài)聯(lián)編。例classA{char*name;public:

A(char*p){strcpy(name,p);}voidprint(){cout<<“\n”<<name;}};classB:publicA{char*grade;public:B(char*p,inti):A(p){grade=i;}voidprint(){A::print();cout<<“\n”<<grade;}};classC:publicA{char*major;public:

C(char*p,char*q):A(p){strcpy(major,q);}voidprint(){A::print();cout<<“\n”<

溫馨提示

  • 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)論