版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1第九章類和對象面向?qū)ο蟮某绦蛟O(shè)計(jì)2按鈕對象:按鈕的內(nèi)容、大小,按鈕的字體、圖案等等針對按鈕的各種操作,創(chuàng)建、單擊、雙擊、拖動(dòng)等班級對象:班級的靜態(tài)特征,所屬的系和專業(yè)、班級的人數(shù),所在的教室等。這種靜態(tài)特征稱為屬性;班級的動(dòng)態(tài)特征,如學(xué)習(xí)、開會(huì)、體育比賽等,這種動(dòng)態(tài)特征稱為行為。3任何一個(gè)對象都應(yīng)當(dāng)具有這兩個(gè)要素,一是屬性(attribute);二是行為(behavior),即能根據(jù)外界給的信息進(jìn)行相應(yīng)的操作。對象是由一組屬性和一組行為構(gòu)成的。面向?qū)ο蟮某绦蛟O(shè)計(jì)采用了以上人們所熟悉的這種思路。使用面向?qū)ο蟮某绦蛟O(shè)計(jì)方法設(shè)計(jì)一個(gè)復(fù)雜的軟件系統(tǒng)時(shí),首要的問題是確定該系統(tǒng)是由哪些對象組成的,并且設(shè)計(jì)這些對象。在C++中,每個(gè)對象都是由數(shù)據(jù)和函數(shù)(即操作代碼)這兩部分組成的。4我們可以對一個(gè)對象進(jìn)行封裝處理,把它的一部分屬性和功能對外界屏蔽,也就是說從外界是看不到的、甚至是不可知的。使用對象的人完全可以不必知道對象內(nèi)部的具體細(xì)節(jié),只需了解其外部功能即可自如地操作對象。
把對象的內(nèi)部實(shí)現(xiàn)和外部行為分隔開來。5傳統(tǒng)的面向過程程序設(shè)計(jì)是圍繞功能進(jìn)行的,用一個(gè)函數(shù)實(shí)現(xiàn)一個(gè)功能。所有的數(shù)據(jù)都是公用的,一個(gè)函數(shù)可以使用任何一組數(shù)據(jù),而一組數(shù)據(jù)又能被多個(gè)函數(shù)所使用。程序設(shè)計(jì)者必須考慮每一個(gè)細(xì)節(jié),什么時(shí)候?qū)κ裁磾?shù)據(jù)進(jìn)行操作。面向?qū)ο蟪绦蛟O(shè)計(jì)采取的是另外一種思路。它面對的是一個(gè)個(gè)對象。實(shí)際上,每一組數(shù)據(jù)都是有特定的用途的,是某種操作的對象。也就是說,一組操作調(diào)用一組數(shù)據(jù)。6程序設(shè)計(jì)者的任務(wù)包括兩個(gè)方面:一是設(shè)計(jì)所需的各種類和對象,即決定把哪些數(shù)據(jù)和操作封裝在一起;二是考慮怎樣向有關(guān)對象發(fā)送消息,以完成所需的任務(wù)。各個(gè)對象的操作完成了,整體任務(wù)也就完成了。
因此人們設(shè)想把相關(guān)的數(shù)據(jù)和操作放在一起,形成一個(gè)整體,與外界相對分隔。這就是面向?qū)ο蟮某绦蛟O(shè)計(jì)中的對象。
7程序=算法+數(shù)據(jù)結(jié)構(gòu)在面向過程的結(jié)構(gòu)化程序設(shè)計(jì)中,人們常使用這樣的公式來表述程序∶
8對象=算法+數(shù)據(jù)結(jié)構(gòu)程序=(對象+對象+對象+……)+消息消息的作用就是對對象的控制。程序設(shè)計(jì)的關(guān)鍵是設(shè)計(jì)好每一個(gè)對象以及確定向這些對象發(fā)出的命令,使各對象完成相應(yīng)的操作。
面向?qū)ο蟮某绦蚪M成:9每一個(gè)實(shí)體都是對象。有一些對象是具有相同的結(jié)構(gòu)和特性的。
每個(gè)對象都屬于一個(gè)特定的類型。
在C++中對象的類型稱為類(class)。類代表了某一批對象的共性和特征。類是對象的抽象,而對象是類的具體實(shí)例(instance)。
10類是一種復(fù)雜的數(shù)據(jù)類型,它是將不同類型的數(shù)據(jù)和與這些數(shù)據(jù)相關(guān)的運(yùn)算封裝在一起的集合體。類的定義類將一些數(shù)據(jù)及與數(shù)據(jù)相關(guān)的函數(shù)封裝在一起,使類中的數(shù)據(jù)得到很好的“保護(hù)”。在大型程序中不會(huì)被隨意修改。11類的定義格式:class類名{private:
成員數(shù)據(jù);
成員函數(shù);
public:
成員數(shù)據(jù);
成員函數(shù);
protected:
成員數(shù)據(jù);
成員函數(shù);};關(guān)鍵字類名私有公有保護(hù)classStudent{private:charName[20];floatMath;floatChiese;
public:floataverage;
voidSetName(char*name);voidSetMath(floatmath);voidSetChinese(floatch);floatGetAverage(void);};分號不能少12用關(guān)鍵字priviate限定的成員稱為私有成員,對私有成員限定在該類的內(nèi)部使用,即只允許該類中的成員函數(shù)使用私有的成員數(shù)據(jù),對于私有的成員函數(shù),只能被該類內(nèi)的成員函數(shù)調(diào)用;類就相當(dāng)于私有成員的作用域。13用關(guān)鍵字public限定的成員稱為公有成員,公有成員的數(shù)據(jù)或函數(shù)不受類的限制,可以在類內(nèi)或類外自由使用;對類而言是透明的。14而用關(guān)鍵字protected所限定的成員稱為保護(hù)成員,只允許在類內(nèi)及該類的派生類中使用保護(hù)的數(shù)據(jù)或函數(shù)。即保護(hù)成員的作用域是該類及該類的派生類。15私有成員公有成員保護(hù)成員類內(nèi)函數(shù)可以調(diào)用可以調(diào)用可以調(diào)用類外函數(shù)不可調(diào)用可以調(diào)用不可調(diào)用私有函數(shù)公有函數(shù)保護(hù)函數(shù)類內(nèi)函數(shù)可以調(diào)用可以調(diào)用可以調(diào)用類外函數(shù)不可調(diào)用可以調(diào)用不可調(diào)用16每一個(gè)限制詞(private等)在類體中可使用多次。一旦使用了限制詞,該限制詞一直有效,直到下一個(gè)限制詞開始為止。如果未加說明,類中成員默認(rèn)的訪問權(quán)限是private,即私有的。17classStudent{ charName[20]; floatMath; floatChiese;
public: floataverage;voidSetName(char*name); voidSetMath(floatmath); voidSetChinese(floatch); floatGetAverage(void);};均為私有權(quán)限均為公有權(quán)限18classA{floatx,y;public:
voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}}; xySetxy()Print()A私有數(shù)據(jù)公有函數(shù)在類外不能直接使用x或y,必須通過Setxy()給x或y賦值,通過Print()輸出x或y。19成員函數(shù)與成員數(shù)據(jù)的定義不分先后,可以先說明函數(shù)原型,再在類體外定義函數(shù)體。classA{floatx,y;public:
voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}}; 在類體內(nèi)定義成員函數(shù)20classA{floatx,y;public:
voidSetxy(floata,floatb);
voidPrint(void);};
voidA::Setxy(floata,floatb){x=a;y=b;}voidA::Print(void){cout<<x<<‘\t’<<y<<endl;}在類體內(nèi)說明成員函數(shù)原型在類體外定義成員函數(shù)21<type><class_name>::<func_name>(<參數(shù)表>){......//函數(shù)體}在類體外定義成員函數(shù)的格式:voidA::Setxy(floata,floatb){x=a;y=b;}函數(shù)類型類名函數(shù)名形參列表函數(shù)體22在定義一個(gè)類時(shí),要注意如下幾點(diǎn):1、類具有封裝性,并且類只是定義了一種結(jié)構(gòu)(樣板),所以類中的任何成員數(shù)據(jù)均不能使用關(guān)鍵字extern,auto或register限定其存儲類型。2、在定義類時(shí),只是定義了一種導(dǎo)出的數(shù)據(jù)類型,并不為類分配存儲空間,所以,在定義類中的數(shù)據(jù)成員時(shí),不能對其初始化。如:classTest{intx=5,y=6;//是不允許的
externfloatx; //是不允許的}23在C++語言中,結(jié)構(gòu)體類型只是類的一個(gè)特例。結(jié)構(gòu)體類型與類的唯一的區(qū)別在于:在類中,其成員的缺省的存取權(quán)限是私有的;而在結(jié)構(gòu)體類型中,其成員的缺省的存取權(quán)限是公有的。24
內(nèi)聯(lián)成員函數(shù)當(dāng)我們定義一個(gè)類時(shí),可以在類中直接定義函數(shù)體。這時(shí)成員函數(shù)在編譯時(shí)是作為內(nèi)聯(lián)函數(shù)來實(shí)現(xiàn)的。同時(shí),我們也可以在類體外定義類的內(nèi)聯(lián)成員函數(shù),在類體內(nèi)說明函數(shù),在類體外定義時(shí),在成員函數(shù)的定義前面加上關(guān)鍵字inline。classA{floatx,y;public:voidSetxy(floata,floatb);
voidPrint(void);}; inlinevoidA::Setxy(floata,floatb){x=a;y=b;}inlinevoidA::Print(void){cout<<x<<‘\t’<<y<<endl;}說明該成員函數(shù)為內(nèi)聯(lián)25對象只有在定義了屬于類的變量后,系統(tǒng)才會(huì)為類的變量分配空間。在定義類時(shí),只是定義了一種數(shù)據(jù)類型,即說明程序中可能會(huì)出現(xiàn)該類型的數(shù)據(jù),并不為類分配存儲空間。類的變量我們稱之為對象。對象是類的實(shí)例,定義對象之前,一定要先說明該對象的類。26不同對象占據(jù)內(nèi)存中的不同區(qū)域,它們所保存的數(shù)據(jù)各不相同,但對成員數(shù)據(jù)進(jìn)行操作的成員函數(shù)的程序代碼均是一樣的?!洞鎯︻愋汀奉惷麑ο?,對象2《,......》;Studentst1,st2;對象的定義格式:類名對象名在建立對象時(shí),只為對象分配用于保存數(shù)據(jù)成員的內(nèi)存空間,而成員函數(shù)的代碼為該類的每一個(gè)對象所共享。27對象的定義方法同結(jié)構(gòu)體定義變量的方法一樣,也分三種,當(dāng)類中有數(shù)據(jù)成員的訪問權(quán)限為私有時(shí),不允許對對象進(jìn)行初始化。classA{floatx,y;public:voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}}a1,a2;voidmain(void){Aa3,a4;}定義全局對象定義局部對象28對象的使用一個(gè)對象的成員就是該對象的類所定義的成員,有成員數(shù)據(jù)和成員函數(shù),引用時(shí)同結(jié)構(gòu)體變量類似,用“.”運(yùn)算符。29classA{floatx,y;public:floatm,n;voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}};voidmain(void){Aa1,a2;//定義對象
a1.m=10;a1.n=20;//為公有成員數(shù)據(jù)賦值
a1.Setxy(2.0,5.0);//為私有成員數(shù)據(jù)賦值
a1.Print();}Print()Setxy()a1nmyxPrint()Setxy()a2nmyx10202.05.0輸出:2 530用成員選擇運(yùn)算符“.”只能訪問對象的公有成員,而不能訪問對象的私有成員或保護(hù)成員。若要訪問對象的私有的數(shù)據(jù)成員,只能通過對象的公有成員函數(shù)來獲取。31classA{floatx,y;public:floatm,n;
voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}};voidmain(void){Aa1,a2;a1.m=10;a1.n=20; //為公有成員數(shù)據(jù)賦值
a1.x=2;a1.y=5;
a1.Setxy(2.0,5.0);
a1.Print();}必須通過類內(nèi)公有函數(shù)訪問私有數(shù)據(jù)成員非法,私有成員不能在類外訪問32同類型的對象之間可以整體賦值,這種賦值與對象的成員的訪問權(quán)限無關(guān)。classA{floatx,y;public:floatm,n;voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}};voidmain(void){Aa1,a2;a1.m=10;a1.n=20; //為公有成員數(shù)據(jù)賦值
a1.Setxy(2.0,5.0);
a2=a1;a1.Print();a2.Print();}同類型的對象之間可以整體賦值相當(dāng)于成員數(shù)據(jù)間相互賦值33對象可以作函數(shù)的入口參數(shù)(實(shí)參、形參),也可以作函數(shù)的出口參數(shù)。這與一般變量作為函數(shù)的參數(shù)是完全相同的。可以定義類類型的指針,類類型的引用,對象數(shù)組,指向類類型的指針數(shù)組和指向一維或多維數(shù)組的指針變量一個(gè)類的對象,可作為另一個(gè)類的成員34類體的區(qū)域稱為類作用域。類的成員函數(shù)與成員數(shù)據(jù),其作用域都是屬于類的作用域,僅在該類的范圍內(nèi)有效,故不能在主函數(shù)中直接通過函數(shù)名和成員名來調(diào)用函數(shù)。類作用域、類類型的作用域和對象的作用域35classA{floatx,y;public:floatm,n;voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}};voidmain(void){Aa1,a2;a1.m=20;a1.n=10;
a1.Setxy(2.0,5.0);
a1.Print();}voidmain(void){Aa1,a2;
m=20;n=10;
Setxy(2.0,5.0);
Print();
}用對象名調(diào)用不能直接調(diào)用36類類型的作用域:在函數(shù)定義之外定義的類,其類名的作用域?yàn)槲募饔糜颍欢诤瘮?shù)體內(nèi)定義的類,其類名的作用域?yàn)閴K作用域。對象的作用域與前面介紹的變量作用域完全相同,全局對象、局部對象、局部靜態(tài)對象等。37classA{floatx,y;public:floatm,n;voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}}a3,a4;voidmain(void){Aa1,a2;
classB{inti,j;public:voidSetij(intm,intn){i=m;j=n;}};Bb1,b2;a1.Setxy(2.0,5.0);b1.Setij(1,2);}類A:文件作用域,在整個(gè)文件中有效類B:塊作用域,在函數(shù)內(nèi)有效。全局對象局部對象38類的嵌套在定義一個(gè)類時(shí),在其類體中又包含了一個(gè)類的完整定義,稱為類的嵌套。類是允許嵌套定義的。39classA{
classB{inti,j;public:voidSetij(intm,intn){i=m;j=n;}};floatx,y;public:
Bb1,b2;voidSetxy(floata,floatb){x=a;y=b;}voidPrint(void){cout<<x<<‘\t’<<y<<endl;}};類B包含在類A中,為嵌套定義嵌套類的對象在類A的定義中,并不為b1,b2分配空間,只有在定義類A的對象時(shí),才為嵌套類的對象分配空間。嵌套類的作用域在類A的定義結(jié)束時(shí)結(jié)束。40類的對象如何引用私有數(shù)據(jù)成員1、通過公有函數(shù)為私有成員賦值classTest{ intx,y;public:voidSetxy(inta,intb){x=a; y=b;}voidPrintxy(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){ Testp1,p2;
p1.Setxy(3,5); p1.Printxy();}調(diào)用公有函數(shù)為私有對象賦值412、利用指針訪問私有數(shù)據(jù)成員classTest{ intx,y;public:voidSetxy(inta,intb){x=a; y=b;}
voidGetxy(int*px,int*py){*px=x;*py=y;}//提取x,y值
voidPrintxy(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){Testp1,p2;p1.Setxy(3,5);inta,b;p1.Getxy(&a,&b);//將a=x,b=ycout<<a<<'\t'<<b<<endl;}Setxy()Getxy()Printxy()xy35ba&apx&bpy35輸出:3 5423、利用函數(shù)訪問私有數(shù)據(jù)成員classTest{ intx,y;public:voidSetxy(inta,intb){x=a; y=b;}
intGetx(void){returnx;}//返回x值
intGety(void){returny;}//返回y值
voidPrintxy(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){Testp1,p2;p1.Setxy(3,5);inta,b;a=p1.Getx();b=p1.Gety();//將a=x,b=ycout<<a<<'\t'<<b<<endl;}函數(shù)值就是私有成員變量的值434、利用引用訪問私有數(shù)據(jù)成員classTest{ intx,y;public:voidSetxy(inta,intb){ x=a;y=b;}
voidGetxy(int&px,int&py){px=x; py=y; }//提取x,y值
voidPrintxy(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){Testp1,p2;p1.Setxy(3,5);inta,b;
p1.Getxy(a,b);//將a=x,b=ycout<<a<<'\t'<<b<<endl;}Setxy()Getxy()Printxy()xy35bapxpy35輸出:3 544類引用舉例(三角形類:三角形的三邊及與三邊相關(guān)的運(yùn)算)classTriangle{private: floata,b,c;//三邊為私有成員數(shù)據(jù)public: voidSetabc(floatx,floaty,floatz);//置三邊的值
voidGetabc(float&x,float&y,float&z);//取三邊的值
floatPerimeter(void);//計(jì)算三角形的周長
floatArea(void);//計(jì)算三角形的面積
voidPrint(void);//打印相關(guān)信息};45voidTriangle::Setabc(floatx,floaty,floatz){a=x;b=y;c=z;}//置三邊的值voidTriangle::Getabc(float&x,float&y,float&z)//取三邊的值
{x=a; y=b; z=c;}floatTriangle::Perimeter(void){return(a+b+c)/2;}//計(jì)算三角形的周長floatTriangle::Area(void)//計(jì)算三角形的面積{floatarea,p;p=Perimeter();area=sqrt((p-a)*(p-b)*(p-c)*p);returnarea;}voidTriangle::Print(void)//打印相關(guān)信息{cout<<"Peri="<<Perimeter()<<'\t'<<"Area="<<Area()<<endl;}46voidmain(void){ TriangleTri1; //定義三角形類的一個(gè)實(shí)例(對象)
Tri1.Setabc(4,5,6); //為三邊置初值
floatx,y,z; Tri1.Getabc(x,y,z);//將三邊的值為x,y,z賦值
cout<<x<<'\t'<<y<<'\t'<<z<<endl; cout<<“s=”<<Tri1.Perimeter()<<endl;//求三角形的周長
cout<<“Area=”<<Tri1.Area()<<endl;//求三角形的面積
cout<<"Tri1:"<<endl; Tri1.Print();//打印有關(guān)信息}47類引用舉例(學(xué)生類:學(xué)生的姓名成績及相關(guān)的運(yùn)算)classStu{ charName[20]; //學(xué)生姓名
floatChinese; //語文成績
floatMath; //數(shù)學(xué)成績public: floatAverage(void); //計(jì)算平均成績
floatSum(void); //計(jì)算總分
voidShow(void); //打印信息
voidSetStudent(char*,float,float);//為對象置姓名、成績
voidSetName(char*); //為對象置姓名
char*GetName(void); //取得學(xué)生姓名};48floatStu::Average(void){return(Chinese+Math)/2;}//平均成績floatStu::Sum(void){returnChinese+Math;}//總分voidStu::Show(void) //打印信息{cout<<"Name:"<<Name<<endl<<"Score:"<<Chinese<<'\t'<<Math<<'\t'<<"average:"<<Average()<<'\t'<<"Sum:"<<Sum()<<endl;}voidStu::SetStudent(char*name,floatchinese,floatmath){ strcpy(Name,name); //置姓名
Chinese=chinese; //置語文成績
Math=math; //置數(shù)學(xué)成績}char*Stu::GetName(void){ returnName;}//返回姓名49voidmain(void){ Stup1,p2; p1.SetStudent(“Liqing”,98,96);//對象置初值
p2.SetStudent("WangGang",90,88);//對象置初值
p1.Show();//打印信息
p2.Show();//打印信息
p1.SetName(“Zhaojian”);//重新置p1對象的名字
p1.Show();cout<<“p1.Name:”<<p1.GetName()<<endl;//打印對象的名字
cout<<“p1.average:”<<p1.Average()<<endl;//打印對象的成績}50成員函數(shù)的重載類中的成員函數(shù)與前面介紹的普通函數(shù)一樣,成員函數(shù)可以帶有缺省的參數(shù),也可以重載成員函數(shù)。重載時(shí),函數(shù)的形參必須在類型或數(shù)目上不同。51classTest{ intx,y; intm,n;public:
voidSetxy(inta,intb){x=a; y=b;}
voidSetxy(inta,intb,intc,intd){x=a;y=b;m=c;n=d;}
voidPrintxy(intx){cout<<“m="<<m<<'\t'<<“n="<<n<<endl;}voidPrintxy(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){ Testp1,p2;
p1.Setxy(3,5);p2.Setxy(10,20,30,40);//參數(shù)不同
p1.Printxy();
p2.Printxy();p2.Printxy(2);//參數(shù)、類型不同}輸出:x=3y=5x=10y=20m=30n=4052classStu{ charName[20]; floatChinese; floatMath;
floatEnglish; floatPhysical;public: floatAverage(void);//語文、數(shù)學(xué)平均成績
floatAverage(intn);//四門課的平均成績
floatSum(void);//語文、數(shù)學(xué)總分
floatSum(intn);//四門課總分
voidShow(void); voidSetStudent(char*,float,float);//置姓名、語文、數(shù)學(xué)初值
voidSetStudent(char*,float,float,float,float);//置姓名、成績
voidSetName(char*); char*GetName(void);};53可以有缺省參數(shù)的成員函數(shù),若形參不完全缺省,則必須從形參的右邊開始缺省。54缺省參數(shù)的成員函數(shù)classA{ floatx,y;public: floatSum(void){returnx+y;}
voidSet(floata,floatb=10.0){x=a; y=b;}voidPrint(void){ cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){ Aa1,a2;
a1.Set(2.0,4.0); cout<<"a1:"; a1.Print(); cout<<"a1.sum="<<a1.Sum()<<endl;
a2.Set(20.0); cout<<"a2:"; a2.Print(); cout<<"a2.sum="<<a2.Sum()<<endl;}不缺省參數(shù),a1.x=2,a1.y=4缺省參數(shù),a2.x=20,a2.y=1055定義類的指針及如何用指針來引用對象classA{ floatx,y;public: floatSum(void){returnx+y;} voidSet(floata,floatb){x=a; y=b;}voidPrint(void){ cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){ Aa1,a2;
A*p; //定義類的指針
p=&a1; //給指針賦值
p->Set(2.0,3.0);//通過指針引用對象的成員函數(shù)
p->Print();cout<<p->Sum()<<endl; a2.Set(10.0,20.0);a2.Print();}Setxy()Getxy()Printxy()xy2.03.0pa156定義類的數(shù)組及數(shù)組中元素的引用voidmain(void){
Stustu[3]; //定義類的數(shù)組
Stu*pstu; //定義類的指針
pstu=stu; //為指針賦值
inti;
stu[0].SetStudent(“A”,90,90);//通過數(shù)組元素的引用賦值
stu[1].SetStudent("B",80,80); stu[2].SetStudent("C",70,70); for(i=0;i<3;i++) {
pstu->Show();//指針變量指向數(shù)組元素
pstu++; //指針變量加一,指向下一元素
}}stupstupstu57返回引用類型的成員函數(shù)(可以返回私有數(shù)據(jù)成員的引用)classA{ floatx,y;public:
float&Getx(void){returnx;} //返回x的引用
voidSet(floata,floatb){x=a;y=b;} voidPrint(void){cout<<x<<'\t'<<y<<endl;}};voidmain(void){ Aa1,a2; a1.Set(3,5); cout<<"a1:"; a1.Print();
a1.Getx()=30; //將a1對象中的x成員賦值
cout<<"changeda1:"; a1.Print();}58線性表的應(yīng)用線性表用來存放若干個(gè)整數(shù),用一個(gè)指針指向其存放整數(shù)的首地址。當(dāng)存放的數(shù)據(jù)大于原先開辟的空間時(shí),線性表自動(dòng)動(dòng)態(tài)開辟空間,儲存所有的整數(shù)。線性表有三個(gè)參數(shù)來描述:指向線性表存儲空間首地址的指針變量List;無符號整數(shù)nMax,指示表的最大長度;無符號整數(shù)nElem,指示表中實(shí)際所放的數(shù)據(jù)個(gè)數(shù)。實(shí)際上,線性表相當(dāng)于一個(gè)整型數(shù)組,List為數(shù)組的首地址,nMax為數(shù)組在內(nèi)存開辟的空間數(shù),nElem為數(shù)組中實(shí)際存放的元素個(gè)數(shù)。只不過數(shù)組的空間是動(dòng)態(tài)開辟的。59classListClass{int*List;//指向線性表的指針
unsignednMax;//表的最大長度
unsignednElem;//表中當(dāng)前的元素個(gè)數(shù)
.......};37924ListnElemnMax空間是動(dòng)態(tài)開辟的60classListClass{int*List;//指向線性表的指針
unsignednMax;//表的最大長度
unsignednElem;//表中當(dāng)前的元素個(gè)數(shù)public: voidInit(intn=10);//初始化針表,最大長度的缺省值為10
voidElem(int); //在線性表尾增加一個(gè)元素
int&Elem(unsignedn); //返回線性表中第n個(gè)元素的引用
unsignedElem(void); //返回當(dāng)前線性表中元素的個(gè)數(shù)
unsignedMax(void); //返回線性表的長度(占用空間數(shù))
voidPrint(void); //輸出線性表中所有的元素
intGetElem(inti); //返回線性表中第i個(gè)元素的值
voidDestroy(void); //收回線性表占用的存儲空間};61voidListClass::Elem(intelem)//在線性表尾增加一個(gè)元素{ nElem=nElem+1; if(nElem>nMax) //空間不夠,動(dòng)態(tài)開辟存儲空間
{ int*list;
list=newint[nMax+1];//開辟一較大的空間
for(inti=0;i<nMax;i++) list[i]=List[i]; nMax=nMax+1; list[i]=elem; delete[]List; List=list; } else { List[nElem-1]=elem; }}重新定義一個(gè)指針list,用其開辟一較大的空間,將原有空間的數(shù)全部拷貝到新的空間,并將新的數(shù)據(jù)放在新空間內(nèi),同時(shí)將舊的空間收回,將線性表的指針指向新空間。62this指針不同對象占據(jù)內(nèi)存中的不同區(qū)域,它們所保存的數(shù)據(jù)各不相同,但對成員數(shù)據(jù)進(jìn)行操作的成員函數(shù)的程序代碼均是一樣的。classA{intx,y;public:voidSetxy(inta,intb){x=a;y=b;}};Aa1,a2;a1.xa1.ya2.xa2.y......x=a;y=b;......a1.Setxy()a2.Setxy()a1.Setxy(1,2);a2.Setxy(3,4);this->x=a;this->y=b;系統(tǒng)自動(dòng)將對象的指針帶到成員函數(shù)中63當(dāng)對一個(gè)對象調(diào)用成員函數(shù)時(shí),編譯程序先將對象的地址賦給this指針,然后調(diào)用成員函數(shù),每次成員函數(shù)存取數(shù)據(jù)成員時(shí),也隱含使用this指針。this指針具有如下形式的缺省說明:
Stu*constthis;類名即this指針里的地址是一個(gè)常量64classS{public:char*strp;intlength;voidIni(char*s);voidPrint(void);voidCopy(S&s);};voidmain(void){ Ss1,s2; s1.Ini(“China”);s2.Ini(“”); s1.Print();s2.Copy(s1);s2.Print();s1.Copy(s1);}voidS::Ini(char*s){length=strlen(s);strp=newchar[length+1];strcpy(strp,s);}voidS::Print(void){cout<<strp<<endl;}voidS::Copy(S&s){if(strp)delete[]strp;length=s.length;strp=newchar[length+1];strcpy(strp,s.strp);}65voidS::Ini(char*s){length=strlen(s);strp=newchar[length+1];strcpy(strp,s);}voidS::Copy(S&s){if(strp)delete[]strp;length=s.length;strp=newchar[length+1];strcpy(strp,s.strp);}*strplengthIni()Print()Copy()S字符串首址字符串長度s1.Ini(“China”);求長度對象動(dòng)態(tài)開辟空間空間賦值length=5strpChina\0s2.Copy(s1);\0strpChina\066voidS::Copy(S&s){if(strp)delete[]strp;length=s.length;strp=newchar[length+1];strcpy(strp,s.strp);}s1.Copy(s1);strpChina\0length=5隨機(jī)隨機(jī)隨機(jī)隨機(jī)隨機(jī)隨機(jī)失去了原來的內(nèi)容,不能正確復(fù)制67voidS::Copy(S&s){if(&s==this)cout<<“不能復(fù)制本身\n”;else{if(strp)delete[]strp;length=s.length;strp=newchar[length+1];strcpy(strp,s.strp);}}判斷是否是自身復(fù)制this為正在調(diào)用該函數(shù)的對象的地址s2.Copy(s1);s1.Copy(s1);if(s==*this)68第十章構(gòu)造函數(shù)和析構(gòu)函數(shù)69構(gòu)造函數(shù)和析構(gòu)函數(shù)是在類體中說明的兩種特殊的成員函數(shù)。構(gòu)造函數(shù)是在創(chuàng)建對象時(shí),使用給定的值來將對象初始化。析構(gòu)函數(shù)的功能正好相反,是在系統(tǒng)釋放對象前,對對象做一些善后工作。70構(gòu)造函數(shù)是類的成員函數(shù),系統(tǒng)約定構(gòu)造函數(shù)名必須與類名相同。構(gòu)造函數(shù)提供了初始化對象的一種簡單的方法。構(gòu)造函數(shù)可以帶參數(shù)、可以重載,同時(shí)沒有返回值。71classA{ floatx,y;public:A(floata,floatb){x=a;y=b;}//構(gòu)造函數(shù),初始化對象floatSum(void){returnx+y;}voidSet(floata,floatb){x=a; y=b;}Print(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){ Aa1(2.0,3.0);//定義時(shí)調(diào)用構(gòu)造函數(shù)初始化
Aa2(1.0,2.0);
a2.Set(10.0,20.0);//利用成員函數(shù)重新為對象賦值
a1.Print(); a2.Print();}72對構(gòu)造函數(shù),說明以下幾點(diǎn):1.構(gòu)造函數(shù)的函數(shù)名必須與類名相同。構(gòu)造函數(shù)的主要作用是完成初始化對象的數(shù)據(jù)成員以及其它的初始化工作。2.在定義構(gòu)造函數(shù)時(shí),不能指定函數(shù)返回值的類型,也不能指定為void類型。3.一個(gè)類可以定義若干個(gè)構(gòu)造函數(shù)。當(dāng)定義多個(gè)構(gòu)造函數(shù)時(shí),必須滿足函數(shù)重載的原則。734.構(gòu)造函數(shù)可以指定參數(shù)的缺省值。5.若定義的類要說明該類的對象時(shí),構(gòu)造函數(shù)必須是公有的成員函數(shù)。如果定義的類僅用于派生其它類時(shí),則可將構(gòu)造函數(shù)定義為保護(hù)的成員函數(shù)。由于構(gòu)造函數(shù)屬于類的成員函數(shù),它對私有數(shù)據(jù)成員、保護(hù)的數(shù)據(jù)成員和公有的數(shù)據(jù)成員均能進(jìn)行初始化。74classA{ floatx,y;public:
A(floata,floatb=10) {x=a;y=b;}
A() {x=0;y=0;}
voidPrint(void){ cout<<x<<'\t'<<y<<endl;}};voidmain(void){Aa1,a2(20.0),a3(3.0,7.0);a1.Print();a2.Print();a3.Print();}0 020 103 7帶缺省參數(shù)的構(gòu)造函數(shù)不帶參數(shù)的構(gòu)造函數(shù)每一個(gè)對象必須要有相應(yīng)的構(gòu)造函數(shù)75每一個(gè)對象必須要有相應(yīng)的構(gòu)造函數(shù)若沒有顯式定義構(gòu)造函數(shù),系統(tǒng)默認(rèn)缺省的構(gòu)造函數(shù)。classA{ floatx,y;public:
A(){}
voidPrint(void){ cout<<x<<'\t'<<y<<endl;}};隱含的缺省的構(gòu)造函數(shù)Aa1,a2;只允許這樣定義對象對象開辟了空間,但沒有初始化76對局部對象,靜態(tài)對象,全局對象的初始化對于局部對象,每次定義對象時(shí),都要調(diào)用構(gòu)造函數(shù)。對于靜態(tài)對象,是在首次定義對象時(shí),調(diào)用構(gòu)造函數(shù)的,且由于對象一直存在,只調(diào)用一次構(gòu)造函數(shù)。對于全局對象,是在main函數(shù)執(zhí)行之前調(diào)用構(gòu)造函數(shù)的。77classA{intx,y;public:
A(inta){x=a;cout<<“1\n”;}A(inta,intb){x=a,y=b;cout<<“2\n”;}};Aa1(3);voidf(void){Ab(2,3);}voidmain(void){Aa2(4,5);f();f();}122278classA{ floatx,y;public:
A(floata,floatb){x=a;y=b;cout<<"初始化自動(dòng)局部對象\n";}
A(){ x=0;y=0;cout<<"初始化靜態(tài)局部對象\n";}
A(floata){ x=a;y=0;cout<<"初始化全局對象\n";}voidPrint(void){cout<<x<<'\t'<<y<<endl;}};Aa0(100.0);//定義全局對象voidf(void){cout<<"進(jìn)入f()函數(shù)\n";Aa2(1,2);
staticAa3;//初始化局部靜態(tài)對象
}voidmain(void){cout<<"進(jìn)入main函數(shù)\n";
Aa1(3.0,7.0);//定義局部自動(dòng)對象
f();f();}初始化全局對象進(jìn)入main函數(shù)初始化自動(dòng)局部對象進(jìn)入f()函數(shù)初始化局部靜態(tài)變量進(jìn)入f()函數(shù)初始化自動(dòng)局部對象初始化自動(dòng)局部對象79缺省的構(gòu)造函數(shù)在定義類時(shí),若沒有定義類的構(gòu)造函數(shù),則編譯器自動(dòng)產(chǎn)生一個(gè)缺省的構(gòu)造函數(shù),其格式為:className::className(){}缺省的構(gòu)造函數(shù)并不對所產(chǎn)生對象的數(shù)據(jù)成員賦初值;即新產(chǎn)生對象的數(shù)據(jù)成員的值是不確定的。80classA{ floatx,y;public:
A(){ }//缺省的構(gòu)造函數(shù),編譯器自動(dòng)產(chǎn)生,可以不寫
floatSum(void){returnx+y;} voidSet(floata,floatb){x=a; y=b;}voidPrint(void){ cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}};voidmain(void){ Aa1,a2;//產(chǎn)生對象時(shí),自動(dòng)調(diào)用缺省的構(gòu)造函數(shù),不賦值
a1.Set(2.0,4.0); cout<<"a1:"; a1.Print(); cout<<"a1.sum="<<a1.Sum()<<endl; a2.Print();//打印隨機(jī)值}81關(guān)于缺省的構(gòu)造函數(shù),說明以下幾點(diǎn):1、在定義類時(shí),只要顯式定義了一個(gè)類的構(gòu)造函數(shù),則編譯器就不產(chǎn)生缺省的構(gòu)造函數(shù)2、所有的對象在定義時(shí),必須調(diào)用構(gòu)造函數(shù)不存在沒有構(gòu)造函數(shù)的對象!82classA{ floatx,y;public:A(floata,floatb) { x=a; y=b; }voidPrint(void){ cout<<x<<'\t'<<y<<endl; }};voidmain(void){ Aa1;
Aa2(3.0,30.0);}顯式定義了構(gòu)造函數(shù),不產(chǎn)生缺省的構(gòu)造函數(shù)error,定義時(shí),沒有構(gòu)造函數(shù)可供調(diào)用833、在類中,若定義了沒有參數(shù)的構(gòu)造函數(shù),或各參數(shù)均有缺省值的構(gòu)造函數(shù)也稱為缺省的構(gòu)造函數(shù),缺省的構(gòu)造函數(shù)只能有一個(gè)。4、產(chǎn)生對象時(shí),系統(tǒng)必定要調(diào)用構(gòu)造函數(shù)。所以任一對象的構(gòu)造函數(shù)必須唯一。84classA{ floatx,y;public:A(floata=10,floatb=20){ x=a; y=b; }A(){}voidPrint(void){ cout<<x<<'\t'<<y<<endl; }};voidmain(void){ Aa1;
Aa2(3.0,30.0);}兩個(gè)函數(shù)均為缺省的構(gòu)造函數(shù)兩個(gè)構(gòu)造函數(shù)均可供調(diào)用,構(gòu)造函數(shù)不唯一85構(gòu)造函數(shù)與new運(yùn)算符
可以使用new運(yùn)算符來動(dòng)態(tài)地建立對象。建立時(shí)要自動(dòng)調(diào)用構(gòu)造函數(shù),以便完成初始化對象的數(shù)據(jù)成員。最后返回這個(gè)動(dòng)態(tài)對象的起始地址。用new運(yùn)算符產(chǎn)生的動(dòng)態(tài)對象,在不再使用這種對象時(shí),必須用delete運(yùn)算符來釋放對象所占用的存儲空間。用new建立類的對象時(shí),可以使用參數(shù)初始化動(dòng)態(tài)空間。86classA{ floatx,y;public:
A(floata,floatb) { x=a;y=b; }
A() { x=0;y=0; } voidPrint(void) {cout<<x<<'\t'<<y<<endl;}};voidmain(void){A*pa1,*pa2;
pa1=newA(3.0,5.0);//用new動(dòng)態(tài)開辟對象空間,初始化
pa2=newA;//用new動(dòng)態(tài)開辟空間,調(diào)用構(gòu)造函數(shù)初始化
pa1->Print();pa2->Print();deletepa1;//用delete釋放空間
deletepa2;//用delete釋放空間}50 087析構(gòu)函數(shù)析構(gòu)函數(shù)的作用與構(gòu)造函數(shù)正好相反,是在對象的生命期結(jié)束時(shí),釋放系統(tǒng)為對象所分配的空間,即要撤消一個(gè)對象。析構(gòu)函數(shù)也是類的成員函數(shù),定義析構(gòu)函數(shù)的格式為:ClassName::~ClassName(){......//函數(shù)體;}88析構(gòu)函數(shù)的特點(diǎn)如下:1、析構(gòu)函數(shù)是成員函數(shù),函數(shù)體可寫在類體內(nèi),也可寫在類體外。2、析構(gòu)函數(shù)是一個(gè)特殊的成員函數(shù),函數(shù)名必須與類名相同,并在其前面加上字符“~”,以便和構(gòu)造函數(shù)名相區(qū)別。3、析構(gòu)函數(shù)不能帶有任何參數(shù),不能有返回值,不指定函數(shù)類型。89在程序的執(zhí)行過程中,當(dāng)遇到某一對象的生存期結(jié)束時(shí),系統(tǒng)自動(dòng)調(diào)用析構(gòu)函數(shù),然后再收回為對象分配的存儲空間。4、一個(gè)類中,只能定義一個(gè)析構(gòu)函數(shù),析構(gòu)函數(shù)不允許重載。5、析構(gòu)函數(shù)是在撤消對象時(shí)由系統(tǒng)自動(dòng)調(diào)用的。90classA{ floatx,y;public:A(floata,floatb){ x=a;y=b;cout<<"調(diào)用非缺省的構(gòu)造函數(shù)\n";}A() {x=0;y=0;cout<<"調(diào)用缺省的構(gòu)造函數(shù)\n";}
~A(){ cout<<"調(diào)用析構(gòu)函數(shù)\n";}voidPrint(void){cout<<x<<'\t'<<y<<endl; }};voidmain(void){ Aa1; Aa2(3.0,30.0); cout<<"退出主函數(shù)\n";}調(diào)用缺省的構(gòu)造函數(shù)調(diào)用非缺省的構(gòu)造函數(shù)退出主函數(shù)調(diào)用析構(gòu)函數(shù)調(diào)用析構(gòu)函數(shù)91
在程序的執(zhí)行過程中,對象如果用new運(yùn)算符開辟了空間,則在類中應(yīng)該定義一個(gè)析構(gòu)函數(shù),并在析構(gòu)函數(shù)中使用delete刪除由new分配的內(nèi)存空間。因?yàn)樵诔废麑ο髸r(shí),系統(tǒng)自動(dòng)收回為對象所分配的存儲空間,而不能自動(dòng)收回由new分配的動(dòng)態(tài)存儲空間。92classStr{ char*Sp;intLength;public:
Str(char*string) {if(string){ Length=strlen(string); Sp=newchar[Length+1]; strcpy(Sp,string); } elseSp=0; } voidShow(void){ cout<<Sp<<endl; }
~Str() {if(Sp) delete[]Sp; }};voidmain(void){ Strs1("StudyC++"); s1.Show();}在構(gòu)造函數(shù)中將成員數(shù)據(jù)指針指向動(dòng)態(tài)開辟的內(nèi)存用初值為開辟的內(nèi)存賦值析構(gòu)函數(shù),當(dāng)釋放對象時(shí)收回用new開辟的空間93‘S’‘t’‘u’‘d’‘y’‘’‘C’‘+’‘+’‘\0’stringLength=strlen(string);Sp=newchar[Length+1];Spnew開辟的空間strcpy(Sp,string);‘S’‘t’‘u’‘d’‘y’‘’‘C’‘+’‘+’‘\0’94用new運(yùn)算符為對象分配動(dòng)態(tài)存儲空間時(shí),調(diào)用了構(gòu)造函數(shù),用delete刪除這個(gè)空間時(shí),調(diào)用了析構(gòu)函數(shù)。當(dāng)使用運(yùn)算符delete刪除一個(gè)由new動(dòng)態(tài)產(chǎn)生的對象時(shí),它首先調(diào)用該對象的析構(gòu)函數(shù),然后再釋放這個(gè)對象占用的內(nèi)存空間??梢杂胣ew運(yùn)算符為對象分配存儲空間,如:A*p;p=newA;這時(shí)必須用delete才能釋放這一空間。deletep;95classA{ floatx,y;public:
A(floata,floatb){ x=a; y=b; cout<<"調(diào)用了構(gòu)造函數(shù)\n";}voidPrint(void){cout<<x<<'\t'<<y<<endl;}
~A() {cout<<"調(diào)用了析構(gòu)函數(shù)\n";}};voidmain(void){cout<<"進(jìn)入main()函數(shù)\n";A*pa1;
pa1=newA(3.0,5.0);//調(diào)用構(gòu)造函數(shù)
pa1->Print();
deletepa1;//調(diào)用析構(gòu)函數(shù)
cout<<"退出main()函數(shù)\n";}進(jìn)入main()函數(shù)調(diào)用了構(gòu)造函數(shù)3 5調(diào)用了析構(gòu)函數(shù)退出main()函數(shù)96不同存儲類型的對象調(diào)用構(gòu)造函數(shù)及析構(gòu)函數(shù)1、對于全局定義的對象(在函數(shù)外定義的對象),在程序開始執(zhí)行時(shí),調(diào)用構(gòu)造函數(shù);到程序結(jié)束時(shí),調(diào)用析構(gòu)函數(shù)。2、對于局部定義的對象(在函數(shù)內(nèi)定義的對象),當(dāng)程序執(zhí)行到定義對象的地方時(shí),調(diào)用構(gòu)造函數(shù);在退出對象的作用域時(shí),調(diào)用析構(gòu)函數(shù)。3、用static定義的局部對象,在首次到達(dá)對象的定義時(shí)調(diào)用構(gòu)造函數(shù);到程序結(jié)束時(shí),調(diào)用析構(gòu)函數(shù)974、對于用new運(yùn)算符動(dòng)態(tài)生成的對象,在產(chǎn)生對象時(shí)調(diào)用構(gòu)造函數(shù),只有使用delete運(yùn)算符來釋放對象時(shí),才調(diào)用析構(gòu)函數(shù)。若不使用delete來撤消動(dòng)態(tài)生成的對象,程序結(jié)束時(shí),對象仍存在,并占用相應(yīng)的存儲空間,即系統(tǒng)不能自動(dòng)地調(diào)用析構(gòu)函數(shù)來撤消動(dòng)態(tài)生成的對象。98classA{ floatx,y;public:
A(floata,floatb){x=a;y=b;cout<<"初始化自動(dòng)局部對象\n";}
A(){ x=0;y=0;cout<<"初始化靜態(tài)局部對象\n";}
A(floata){ x=a;y=0;cout<<"初始化全局對象\n";}~A(){cout<<“調(diào)用析構(gòu)函數(shù)”<<endl;}};Aa0(100.0);//定義全局對象voidf(void){cout<<"進(jìn)入f()函數(shù)\n";
Aab(10.0,20.0);//定義局部自動(dòng)對象
staticAa3;//初始化局部靜態(tài)對象
}voidmain(void){cout<<"進(jìn)入main函數(shù)\n";f();f();}初始化全局對象進(jìn)入main函數(shù)初始化自動(dòng)局部對象進(jìn)入f()函數(shù)初始化靜態(tài)局部對象進(jìn)入f()函數(shù)初始化自動(dòng)局部對象調(diào)用析構(gòu)函數(shù)調(diào)用析構(gòu)函數(shù)調(diào)用析構(gòu)函數(shù)調(diào)用析構(gòu)函數(shù)99舉例:建立一個(gè)類NUM,求指定數(shù)據(jù)范圍內(nèi)的所有素?cái)?shù)。如:定義類NUM的對象test,查找范圍為100~200,正確的輸出結(jié)果:num=21101103107109113127131……100動(dòng)態(tài)構(gòu)造及析構(gòu)對象數(shù)組用new運(yùn)算符來動(dòng)態(tài)生成對象數(shù)組時(shí),自動(dòng)調(diào)用構(gòu)造函數(shù),而用delete運(yùn)算符來釋放p1所指向的對象數(shù)組占用的存儲空間時(shí),在指針變量的前面必須加上[],才能將數(shù)組元素所占用的空間全部釋放。否則,只釋放第0個(gè)元素所占用的空間。pa1=newA[3];.....delete[]pa1;101classA{ floatx,y;public:A(floata=0,floatb=0){x=a;y=b;cout<<"調(diào)用了構(gòu)造函數(shù)\n";}voidPrint(void){cout<<x<<'\t'<<y<<endl;}~A(){cout<<"調(diào)用了析構(gòu)函數(shù)\n";}};voidmain(void){cout<<"進(jìn)入main()函數(shù)\n";A*pa1;pa1=newA[3];//開辟數(shù)組空間
cout<<"\n完成開辟數(shù)組空間\n\n";delete[]pa1;//必須用[]刪除開辟的空間
cout<<"退出main()函數(shù)\n";}進(jìn)入main()函數(shù)調(diào)用了構(gòu)造函數(shù)調(diào)用了構(gòu)造函數(shù)調(diào)用了構(gòu)造函數(shù)完成開辟數(shù)組空間調(diào)用了析構(gòu)函數(shù)調(diào)用了析構(gòu)函數(shù)調(diào)用了析構(gòu)函數(shù)退出main()函數(shù)102缺省的析構(gòu)函數(shù)若在類的定義中沒有顯式地定義析構(gòu)函數(shù)時(shí),則編譯器自動(dòng)地產(chǎn)生一個(gè)缺省的析構(gòu)函數(shù),其格式為:ClassName::~ClassName(){};任何對象都必須有構(gòu)造函數(shù)和析構(gòu)函數(shù),但在撤消對象時(shí),要釋放對象的數(shù)據(jù)成員用new運(yùn)算符分配的動(dòng)態(tài)空間時(shí),必須顯式地定義析構(gòu)函數(shù)。103實(shí)現(xiàn)類型轉(zhuǎn)換的構(gòu)造函數(shù)同類型的對象可以相互賦值,相當(dāng)于類中的數(shù)據(jù)成員相互賦值;如果直接將數(shù)據(jù)賦給對象,所賦入的數(shù)據(jù)需要強(qiáng)制類型轉(zhuǎn)換,這種轉(zhuǎn)換需要調(diào)用構(gòu)造函數(shù)。104classA{ floatx,y;public:
A(floata,floatb){x=a;y=b;cout<<"調(diào)用構(gòu)造函數(shù)\n";}~A() { cout<<"調(diào)用析構(gòu)函數(shù)\n";}voidPrint(void){cout<<x<<'\t'<<y<<endl; }};voidmain(void){Aa1(1.0,10.0);a1.Print();
a1=A(3.0,30.0);a1.Print();cout<<"退出主函數(shù)\n";}調(diào)用構(gòu)造函數(shù)產(chǎn)生臨時(shí)對象,初始化并賦值后立即釋放110調(diào)用構(gòu)造函數(shù)調(diào)用析構(gòu)函數(shù)3 30退出主函數(shù)調(diào)用析構(gòu)函數(shù)105注意:當(dāng)構(gòu)造函數(shù)只有一個(gè)參數(shù)時(shí),可以用=強(qiáng)制賦值。classB{ floatx;public:B(floata){x=a;cout<<"調(diào)用構(gòu)造函數(shù)\n";}~B() {cout<<"調(diào)用析構(gòu)函數(shù)\n";}voidPrint(void){cout<<x<<endl;}};voidmain(void){Bb1(1.0); b1.Print();Bb2=100;b2.Print();
b1=10; b1.Print();cout<<"退出主函數(shù)\n";}調(diào)用構(gòu)造函數(shù)單參數(shù)可以這樣賦值1調(diào)用構(gòu)造函數(shù)100調(diào)用構(gòu)造函數(shù)調(diào)用析構(gòu)函數(shù)10退出主函數(shù)調(diào)用析構(gòu)函數(shù)調(diào)用析構(gòu)函數(shù)b1=B(10)產(chǎn)生一個(gè)臨時(shí)對象106完成拷貝功能的構(gòu)造函數(shù)可以在定義一個(gè)對象的時(shí)候用另一個(gè)對象為其初始化,即構(gòu)造函數(shù)的參數(shù)是另一個(gè)對象的引用,這種構(gòu)造函數(shù)常為完成拷貝功能的構(gòu)造函數(shù)。完成拷貝功能的構(gòu)造函數(shù)的一般格式為:ClassName::ClassName(ClassName&<變量名>){ ......//函數(shù)體完成對應(yīng)數(shù)據(jù)成員的賦值}107classA{ floatx,y;public:
A(floata=0,floatb=0){x=a;y=b;}A(A&a){x=a.x;y=a.y;}};voidmain(void){Aa1(1.0,2.0);
Aa2(a1);}形參必須是同類型對象的引用實(shí)參是同類型的對象108classA{ floatx,y;public:
A(floata=0,floatb=0){x=a;y=b; cout<<"調(diào)用了構(gòu)造函數(shù)\n";}
A(A&a){x=a.x;y=a.y;cout<<“調(diào)用了完成拷貝功能的構(gòu)造函數(shù)\n”;}voidPrint(void){cout<<x<<'\t'<<y<<endl;}~A(){cout<<"調(diào)用了析構(gòu)函數(shù)\n";}};voidmain(void){Aa1(1.0,2.0);
Aa2(a1);a1.Print();a2.Print(); }調(diào)用了構(gòu)造函數(shù)調(diào)用了完成拷貝功能的構(gòu)造函數(shù)1 21 2調(diào)用了析構(gòu)函數(shù)調(diào)用了析構(gòu)函數(shù)用已有的對象中的數(shù)據(jù)為新創(chuàng)建的對象賦值109如果沒有定義完成拷貝功能的構(gòu)造函數(shù),編譯器自動(dòng)生成一個(gè)隱含的完成拷貝功能的構(gòu)造函數(shù),依次完成類中對應(yīng)數(shù)據(jù)成員的拷貝。A::A(A&a){x=a.x;y=a.y;}隱含的構(gòu)造函數(shù)110c
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 養(yǎng)老院老人健康飲食營養(yǎng)師表彰制度
- 人教版教學(xué)課件免疫調(diào)節(jié)(上課)
- 《石油和油品》課件
- 整體驗(yàn)收合同模板(2篇)
- 2024年特定項(xiàng)目資產(chǎn)抵押融資合同范本版B版
- 2025年東營貨運(yùn)從業(yè)資格證試題庫及答案
- 2024年生態(tài)農(nóng)業(yè)用地流轉(zhuǎn)合作合同范本3篇
- 2025年蘇州貨運(yùn)考試題庫
- 2025年巴中貨運(yùn)上崗證考試題
- 2025年黔南貨運(yùn)上崗證考試題庫
- 學(xué)歷提升之路
- 遼寧省大連市沙河口區(qū)2022-2023學(xué)年八年級上學(xué)期物理期末試卷(含答案)
- 做賬實(shí)操-鞋廠的賬務(wù)處理
- 承插盤扣懸挑腳手架施工方案
- 播音主持專業(yè)教學(xué)計(jì)劃
- 2024年醫(yī)師定期考核臨床類人文醫(yī)學(xué)知識考試題庫及答案(共280題)
- 江蘇省南通市2024屆高三上學(xué)期第一次調(diào)研測試(一模)生物 含答案
- 2024年度企業(yè)數(shù)字化轉(zhuǎn)型服務(wù)合同
- 會(huì)議服務(wù)的合同范本(8篇)
- 電梯困人應(yīng)急演練方案
- 【初中歷史】西晉的短暫統(tǒng)一和北方各族的內(nèi)遷課件 2024-2025學(xué)年統(tǒng)編版七年級歷史上冊
評論
0/150
提交評論