




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
3.3靜態(tài)類成員3.3.1靜態(tài)數(shù)據(jù)成員
希望數(shù)據(jù)為類的所有對象共享,而不是每個類對象維持一個獨立的數(shù)據(jù)成員。例如:計數(shù)在程序的任意一點一共創(chuàng)建了多少個此類類型的對象。靜態(tài)數(shù)據(jù)成員對每個類類型只有一個拷貝,由該類對象共享訪問。非靜態(tài)數(shù)據(jù)成員對每個類對象都有自己的拷貝。可以實現(xiàn)信息隱藏,可以是private成員。3.3.1.1類定義內(nèi)聲明在類體中數(shù)據(jù)成員聲明前加上static關(guān)鍵字,使該數(shù)據(jù)成員成為靜態(tài)的例如:classstudent{intnum;floatscore;public:staticfloatpassmark;staticintpassnum;3.3靜態(tài)類成員1student(inta,floatf){num=a;score=f;}};3.3.1.2類定義外初始化
¤語法:數(shù)據(jù)類型類名::數(shù)據(jù)成員名=初值;注意:①如果沒有初值,系統(tǒng)自動初始化為0。②整型const靜態(tài)數(shù)據(jù)成員可以在類定義體內(nèi)用常量值初始化,但仍要在類定義體外定義該數(shù)據(jù)成員且不能再指定初始值。③靜態(tài)數(shù)據(jù)成員的初始化不應(yīng)該放在頭文件中。一般放在類定義之后,main函數(shù)之前。產(chǎn)生類對象之前可能用到靜態(tài)數(shù)據(jù)成員。例如:classAccout{{staticconstintnamesize=16;staticconstcharname[namesize];};constintAccout::namesize;constcharAccout::name[namesize]=”savingaccount”;3.3.1.3靜態(tài)數(shù)據(jù)成員的訪問student(inta,flo2類的成員函數(shù)中訪問:用靜態(tài)數(shù)據(jù)成員名直接訪問非成員函數(shù)中訪問public靜態(tài)數(shù)據(jù)成員:類名::靜態(tài)數(shù)據(jù)成員名對象.靜態(tài)數(shù)據(jù)成員名指向?qū)ο蟮闹羔?>靜態(tài)數(shù)據(jù)成員名例如:計數(shù)已創(chuàng)建對象的數(shù)目classData{intnum;floatscore;public:staticintobject;Data(inta,floatf):num(a),score(f){object++;}~Data(){object--;}};類的成員函數(shù)中訪問:用靜態(tài)數(shù)據(jù)成員名直接訪問33.3.2靜態(tài)成員函數(shù)
希望在產(chǎn)生對象之前訪問private靜態(tài)數(shù)據(jù)成員3.3.2.1聲明與定義在類內(nèi)普通成員函數(shù)聲明前加上static關(guān)鍵字,在類外定義前不需再加static。注意:靜態(tài)成員函數(shù)沒有this指針,不能訪問類的非靜態(tài)成員,只能訪問類的靜態(tài)數(shù)據(jù)成員或是調(diào)用其它靜態(tài)成員函數(shù)。3.3.2.2調(diào)用類名::靜態(tài)函數(shù)名(參數(shù)表);對象.靜態(tài)函數(shù)名(參數(shù)表);指向?qū)ο蟮闹羔?>靜態(tài)函數(shù)名(參數(shù)表);例如:classSmall{staticintobject;public:Small(){object++;}staticintget_n(){returnobject;}3.3.2靜態(tài)成員函數(shù)4~Small(){object--;}};intSmall::object=0;intmain(){intn;n=Small::get_n();//…}3.3.3全局、靜態(tài)局部類對象
3.3.3.1局部靜態(tài)類對象在函數(shù)或復(fù)合語句內(nèi),用static關(guān)鍵字定義的對象。例如:intfun(){staticData(1,89.0);return0;}代碼執(zhí)行過程中第一次遇到該對象定義時,構(gòu)造函數(shù)被調(diào)用,程序運行中僅調(diào)用一次;在程序運行結(jié)束前,調(diào)用析構(gòu)函數(shù),也只調(diào)用一次。例如:~Small(){o5classdemo{public:demo(){cout<<”objectconstructor\n”;}~demo(){cout<<”objectdestructor\n”}};voidfun(){staticdemod1;}intmain(){cout<<"mainstart\n";fun();cout<<"again\n";fun();輸出:mainstartcout<<"mainend\n";}objectconstructoragainmainendobjectdestructorclassdemo{63.3.3.2全局類對象在函數(shù)外定義的對象。構(gòu)造函數(shù)在main函數(shù)執(zhí)行前被調(diào)用,析構(gòu)函數(shù)在程序運行結(jié)束前調(diào)用。例如:classdemo{public: demo(){cout<<"objectconstructor\n";} ~demo(){cout<<"objectdestructor\n";}};intmain(){ cout<<"mainstart\n";cout<<"mainend\n";return0;}輸出:objectconstructorstaticdemod1;mainstartmainendobjectdestructor3.3.3.2全局類對象73.4友元3.4.1友元函數(shù)3.4.1.1友元函數(shù)的聲明允許一個類授權(quán)其它的函數(shù)或類訪問它的非公有成員。友元聲明以friend關(guān)鍵字開頭,只能出現(xiàn)在類的定義中。友元不是類的成員,不受訪問說明符的影響。一般將類中所有友元關(guān)系的聲明放在類頭之后。
¤語法:friend數(shù)據(jù)類型函數(shù)名(參數(shù)標(biāo));3.4.1.2友元函數(shù)的參數(shù)成員函數(shù)由對象調(diào)用,系統(tǒng)傳遞this指針使其可以訪問對象的成員。友元函數(shù)沒有this指針,要訪問對象的成員,必須將要訪問的對象作為參數(shù)傳遞。訪問類對象的成員必須加上對象名和成員訪問運算符。例如:classData{friendvoidget_val(Data&it,intn,floats);intnum;floatscore;3.4友元8public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}voidprint();};voidData::print(){cout<<num<<“\n”<<score<<“\n”;}voidset_val(Data&it,intn,floats){it.num=n;it.score=s;}intmain(){Datamydata;set_val(mydata,1,67.0);mydata.print();return0;}public:93.4.2友元類3.4.2.1友元類的聲明在類的定義體內(nèi)聲明
¤語法:friendclass類名;友元類的所有成員函數(shù)都可以訪問授權(quán)類的成員。友元關(guān)系是單向的,A是B的友元,但B不是A的友元。例如:classData{friendclassTeacher;intnum;floatscore;public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}voidprint();};3.4.2友元類10classTeacher{public:voidset_data(Data&it,intn,floats){it.num=n;it.score=s;}};intmain(){Datamydata;Teachertheteacher;theteacher.set_data(mydata,1,87.0);return0;}注意:Teacher類的定義應(yīng)在Data類之后。3.4.2.2類的成員函數(shù)作為友元函數(shù)若授權(quán)類的友元類中只有一個成員函數(shù)要訪問授權(quán)類的成員,可以只將該成員函數(shù)作為授權(quán)類的友元函數(shù)。classTeacher{11友元類必須在授權(quán)類之前定義,但是授權(quán)類要在友元類之前作前向聲明。只有當(dāng)一個類的定義已經(jīng)被看到時,其成員函數(shù)才能被聲明為另一個類的友元。例如:classData;//聲明classTeacher{public:voidset_data(Data&it,intn,floats){it.num=n;it.score=s;}};classData{friendvoidTeacher::set_data(Data&it,intn,floats);intnum;floatscore;public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}};友元類必須在授權(quán)類之前定義,但是授權(quán)類要在友元類之前作12第4章運算符重載4.1算術(shù)運算符+、-可以對任意基本類型進行“+”運算,例如:3+4.7、5+’a’,c語言本身已經(jīng)重載了該運算符,所以它能夠用于int、float、double和其他內(nèi)部定義類型的變量.如果希望“+”運算可以應(yīng)用在類對象上,如:data1+data2,需要以函數(shù)的形式重新定義“+”運算執(zhí)行的行為,稱為運算符的重載。注意:①只能對用戶自定義的數(shù)據(jù)類型重載運算符,即運算符重載函數(shù)的參數(shù)至少有一個必須是類的對象或者是對類的對象的引用。②運算符重載實際是定義函數(shù),調(diào)用函數(shù)時實參不是出現(xiàn)在圓括號內(nèi),而是在運算符的旁邊,函數(shù)名是由關(guān)鍵字operator和其后要重載的運算符符號組成的。③重載不能改變運算符的優(yōu)先級、結(jié)合性。④重載不能改變運算符操作數(shù)的個數(shù)和運算符本身的含義。⑤不能創(chuàng)建新的運算符,只有現(xiàn)有的運算符才能被重載。
4.1.1作為普通(友元)函數(shù)重載
定義:數(shù)據(jù)類型operator+(參數(shù)表){}例如:classdemo{frienddemooperator+(demo&d1,demo&d2);第4章運算符重載13inta;floatb;public:demo(intx,floaty){a=x;b=y;}};demooperator+(demo&d1,demo&d2)//不能返回引用,局部對象temp//在函數(shù)結(jié)束后內(nèi)存空間被釋放{demotemp(0,0.0);temp.a=d1.a+d2.a;temp.b=d1.b+d2.b;returntemp;}或者:demooperator+(demo&d1,demo&d2){returndemo(d1.a+d2.a,d1.b+d2.b);}調(diào)用:對象+對象例如:inta;14demodemo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;//相當(dāng)于demo3=operator+(demo1,demo2);demooperator+(demo&d1,demo&d2)希望實現(xiàn)調(diào)用:對象+整數(shù)demooperator+(demo&d1,intx){demotemp(0,0.0);temp.a=d1.a+x;temp.b=d1.b+xreturntemp;}調(diào)用:demodemo1(2,3.2),demo2;demo2=demo1+5;//不能寫成demo2=5+demo1;demooperator+(demo&d1,intx)demodemo1(2,3.2),demo2(115希望實現(xiàn)調(diào)用:整數(shù)+對象demooperator+(intx,demo&d1){demotemp(0,0.0);temp.a=d1.a+x;temp.b=d1.b+xreturntemp;}調(diào)用:demodemo1(2,3.2),demo2;demo2=5+demo1;//相當(dāng)于demo2=operator+(5,demo1);4.1.2作為成員函數(shù)重載表示該類對象與另一個操作數(shù)進行運算。該類對象作為操作數(shù)1。成員函數(shù)將指向調(diào)用成員函數(shù)的類對象的this指針作為第一個參數(shù),所以重載運算符函數(shù)需要的參數(shù)個數(shù)為運算符的操作數(shù)個數(shù)-1。調(diào)用運算符重載函數(shù)時,運算符左側(cè)的操作數(shù)為調(diào)用成員函數(shù)的該類對象,右側(cè)的操作數(shù)為傳遞給成員函數(shù)的參數(shù)。例如:希望實現(xiàn)調(diào)用:整數(shù)+對象16classdemo{inta;floatb;public:demo(intx,floaty){a=x;b=y;}
demooperator+(demo&it);//相當(dāng)于demooperator+(demo*this,demo&it);};希望實現(xiàn)調(diào)用:對象+對象demodemo::operator+(demo&it){demotemp(0,0.0);temp.a=a+it.a;temp.b=b+it.b;returntemp;}例如:demodemo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;//相當(dāng)于demo3=demo1.operator+(demo2);classdemo{17希望實現(xiàn)調(diào)用:對象+整數(shù)demodemo::operator+(intx){demotemp(0,0.0);temp.a=a+xtemp.b=b+x;returntemp;}例如:demodemo1(2,3.2),demo2;demo2=demo1+5;//相當(dāng)于demo2=demo1.operator+(5);//不能寫成demo2=5+demo1;希望實現(xiàn)調(diào)用:整數(shù)+對象,不能定義成成員函數(shù)。如果運算符的左側(cè)操作數(shù)不是類類型而是其它類型,重載運算符函數(shù)只能作為友元函數(shù)。4.2運算符++、--
4.1.1作為普通(友元)函數(shù)重載前置運算符:希望實現(xiàn)調(diào)用:對象+整數(shù)18定義:數(shù)據(jù)類型operator++(參數(shù)表);例如:classdemo{frienddemo&operator++(demo&it);inta;floatb;public:demo(intx,floaty){a=x;b=y;}};demo&operator++(demo&it){it.a++;it.b++;returnit;}調(diào)用:++對象例如:demodemo1(2,3.2);++demo1;//相當(dāng)于operator++(demo1)定義:數(shù)據(jù)類型operator++(參數(shù)表);19后置運算符:需要增加一個額外的參數(shù)例如:demooperator++(demo&it,int){demotemp(it);//調(diào)用拷貝構(gòu)造函數(shù)it.a++;it.b++;returntemp;}調(diào)用:對象++例如:demodemo1(2,3.2);5+demo1++;//相當(dāng)于operator++(demo1,int)4.2.2作為成員函數(shù)
前置運算符:例如:classdemo{inta;floatb;后置運算符:需要增加一個額外的參數(shù)20public:demo(intx,floaty){a=x;b=y;}demo&operator++();};demo&demo::operator++(){a++;b++;return*this;}調(diào)用:demodemo1(2,3.2);++demo1;//相當(dāng)于demo1.operator++()后置運算符:增加一個額外的參數(shù)demodemo::operator++(int){demotemp=*this;//調(diào)用拷貝構(gòu)造函數(shù)a++;b++;returntemp;}public:21調(diào)用:demodemo1(2,3.2);5+demo1++;//相當(dāng)于demo1.operator++(int)4.3賦值運算符=的重載
運算符()、[]、->,或者任何賦值運算符重載函數(shù)必須聲明為類的一個成員函數(shù)。賦值運算符重載用于“=”兩側(cè)的對象都已經(jīng)存在時,一個類對象向該類的另一個對象賦值。一般在對象的數(shù)據(jù)成員是指針時用來進行深層復(fù)制。例如:demod1(1,4.2);//構(gòu)造函數(shù)demod2=d1;//拷貝構(gòu)造函數(shù)d3=d2;//賦值注意:①確保沒有將對象復(fù)制給它自身②重新使用被賦值對象中的資源或刪除它③從源對象上復(fù)制內(nèi)容到目的對象例如:classTstring{char*str;調(diào)用:demodemo1(2,3.2);22intlen;public:Tstring(constchar*p);~Tstring(){delete[]str;}Tstring(constTstring&source);Tstring&operator=(Tstring&it);};Tstring&Tstring::operator=(Tstring&it){if(this==&it)return*this;delete[]str;len=it.len;str=newchar[len]strcpy(str,it.str);return*this;}intlen;23賦值運算符重載也可以用于為一個類對象賦以不是該類類型的值。例如希望實現(xiàn)如下賦值:Tstringcar(“benz”);car=“bmw”;在類定義中增加成員函數(shù):Tstring&operator=(constchar*);Tstring&Tstring::operator=(constchar*cst){if(cst==0){len=0;delete[]str;str=0;}else{len=strlen(cst)+1;delete[]str;str=newchar[len]strcpy(str,it.cst);}return*this;}賦值運算符重載也可以用于為一個類對象賦以不是該類類型的值244.4下標(biāo)運算符[]的重載可以重載用于檢查數(shù)組的下標(biāo)是否越界定義:operator[](intindex){}調(diào)用:對象[下標(biāo)]出現(xiàn)在賦值運算符左側(cè),應(yīng)該返回左值(指針、引用),出現(xiàn)在賦值運算符右側(cè),應(yīng)該返回元素的值,但是函數(shù)只有一種返回類型,只有返回引用可以作為左值。例如:classintarray{intsize;int*ip;public:intarray(unsignedmaxsize){size=maxsize;ip=newint[size];}~intarray(){delete[]ip;}4.4下標(biāo)運算符[]的重載25int&operator[](index);};int&intarray::operator[](index){if(index<0||index>=size){cout<<”outofrange!\n”;exit(1);}returnip[index];}intmain(){intsize=100;intarrya(size);for(inti=0;i<size;i++)a[i]=i;…}int&operator[](in264.5成員訪問運算符->的重載
賦予類類型類似指針的行為定義:數(shù)據(jù)類型operator->(){}調(diào)用:對象->成員,相當(dāng)于:(對象.operator->())->成員注意:①對->的重載必須返回指向類對象的指針②->后的成員必須是返回的指針可以訪問的成員③在返回的指針上再應(yīng)用->以訪問該成員。例如:
4.5成員訪問運算符->的重載27classfoo{public:intm;};classz{public:foof;foo*operator->(){return&f;}};intmain(){zz1;z1->m=0;}//可用于訪問對象成員的成員4.6函數(shù)調(diào)用運算符()的重載重載了()運算符的對象稱為functionobject,可作為函數(shù)來使用classfoo{28定義:數(shù)據(jù)類型operator()(參數(shù)表){}調(diào)用:類對象(參數(shù)表)例如:classlessthan{intval;public:lessthan(intx){val=x;}booloperator()(intvalue)const;};boollessthan::operator()(intvalue)const{returnvalue<val;}intmain(){lessthanit(10);inta=5;if(it(a))cout<<”lessthan”;return0;}定義:數(shù)據(jù)類型operator()(參數(shù)表){}29例如:classabsint{public:intoperator()(intvalue){intresult=value<0?-value:value;returnresult;}};intmain(){absintitabs;inta;cin>>a;cout<<itabs(a);return0;}
4.7用戶定義的轉(zhuǎn)換
隱式調(diào)用例如:classabsint{304.7.1構(gòu)造函數(shù)作為轉(zhuǎn)換函數(shù)只有一個基本類型參數(shù)(可以還有其它缺省參數(shù))的構(gòu)造函數(shù),可以作為類型轉(zhuǎn)換構(gòu)造函數(shù),實現(xiàn)轉(zhuǎn)換:基本類型類類型使用構(gòu)造函數(shù)執(zhí)行隱式轉(zhuǎn)換時,構(gòu)造函數(shù)參數(shù)類型不必與被轉(zhuǎn)換值的類型完全一致,編譯器會在調(diào)用構(gòu)造函數(shù)執(zhí)行用戶定義的轉(zhuǎn)換之前,對實參應(yīng)用標(biāo)準(zhǔn)轉(zhuǎn)換。例如:classdemo{frienddemooperator+(demo&d1,demo&d2);inta;public:demo(intx=0)//intdemo{a=x;}};intmain(){demod1(3),d2;d2=5+d1;//5demo,相當(dāng)于demotemp(5);d2=temp+d1;d2=d1+4.2;//4.2intdemo4.7.1構(gòu)造函數(shù)作為轉(zhuǎn)換函數(shù)31類A的構(gòu)造函數(shù)將類B的對象(或引用)作為它的單個參數(shù),可以作為類型轉(zhuǎn)換構(gòu)造函數(shù),實現(xiàn)轉(zhuǎn)換:B類類型A類類型例如:classB{public:B(){}};classA{public:A(B&b){}};voidfun(Aa){}intmain(){Bb1;fun(b1);}//相當(dāng)于Atemp(b1);//fun(temp);調(diào)用構(gòu)造函數(shù)A(b1)把b1轉(zhuǎn)換成A類型的值。編譯器調(diào)用構(gòu)造函數(shù)創(chuàng)建一個A類型臨時對象,將臨時對象的值傳遞給fun()函數(shù)。類A的構(gòu)造函數(shù)將類B的對象(或引用)作為它的單個參數(shù)324.7.2類型轉(zhuǎn)換運算符重載(轉(zhuǎn)換函數(shù))
定義:operator類型(){}實現(xiàn)類類型和轉(zhuǎn)換函數(shù)中指定的類型之間的轉(zhuǎn)換注意:①轉(zhuǎn)換函數(shù)不允許定義返回類型,但必須有返回值。②只能定義成類的成員函數(shù),轉(zhuǎn)換函數(shù)中指定的類型可以是內(nèi)置類型、類類型。例如:classdemo{demooperator+(demo&d1,demo&d2);inta;floatb;public:demo(intx,floaty){a=x;b=y;}operatorint(){returna;}
};4.7.2類型轉(zhuǎn)換運算符重載(轉(zhuǎn)換函數(shù))33intmain(){demod1(4,7.5);inta=5+d1;//調(diào)用d1.operatorint()將d1intdoublef=d1+3.9;//調(diào)用d1.operatorint()將d1intdoublecout<<a<<”\n”<<f<<”\n”;}4.7.3構(gòu)造函數(shù)和轉(zhuǎn)換函數(shù)的相互影響
轉(zhuǎn)換函數(shù)執(zhí)行后,可以用標(biāo)準(zhǔn)轉(zhuǎn)換把轉(zhuǎn)換函數(shù)的結(jié)果轉(zhuǎn)換成目標(biāo)類型;在構(gòu)造函數(shù)執(zhí)行轉(zhuǎn)換之前,可以用標(biāo)準(zhǔn)轉(zhuǎn)換把要轉(zhuǎn)換的值轉(zhuǎn)換成構(gòu)造函數(shù)參數(shù)的類型?,F(xiàn)類型目標(biāo)類型轉(zhuǎn)換序列:標(biāo)準(zhǔn)轉(zhuǎn)換用戶定義的轉(zhuǎn)換標(biāo)準(zhǔn)轉(zhuǎn)換當(dāng)不只一個轉(zhuǎn)換序列可以被應(yīng)用時,編譯器必須選擇最好的序列執(zhí)行轉(zhuǎn)換。標(biāo)準(zhǔn)轉(zhuǎn)換成為選擇的依據(jù)。若所有的轉(zhuǎn)換都一樣好,則出現(xiàn)二義性。例如:classdemo{inta;public:intmain()34demo(intx=0)//intdemo{a=x;}operatorint(){returna;}operatorfloat(){returna;}};intmain(){demod1(3);longv=d1;}//調(diào)用d1.operatorint()將d1intlong//調(diào)用d1.operatorfloat()將d1floatlongdemo(intx=0)//intde353.3靜態(tài)類成員3.3.1靜態(tài)數(shù)據(jù)成員
希望數(shù)據(jù)為類的所有對象共享,而不是每個類對象維持一個獨立的數(shù)據(jù)成員。例如:計數(shù)在程序的任意一點一共創(chuàng)建了多少個此類類型的對象。靜態(tài)數(shù)據(jù)成員對每個類類型只有一個拷貝,由該類對象共享訪問。非靜態(tài)數(shù)據(jù)成員對每個類對象都有自己的拷貝??梢詫崿F(xiàn)信息隱藏,可以是private成員。3.3.1.1類定義內(nèi)聲明在類體中數(shù)據(jù)成員聲明前加上static關(guān)鍵字,使該數(shù)據(jù)成員成為靜態(tài)的例如:classstudent{intnum;floatscore;public:staticfloatpassmark;staticintpassnum;3.3靜態(tài)類成員36student(inta,floatf){num=a;score=f;}};3.3.1.2類定義外初始化
¤語法:數(shù)據(jù)類型類名::數(shù)據(jù)成員名=初值;注意:①如果沒有初值,系統(tǒng)自動初始化為0。②整型const靜態(tài)數(shù)據(jù)成員可以在類定義體內(nèi)用常量值初始化,但仍要在類定義體外定義該數(shù)據(jù)成員且不能再指定初始值。③靜態(tài)數(shù)據(jù)成員的初始化不應(yīng)該放在頭文件中。一般放在類定義之后,main函數(shù)之前。產(chǎn)生類對象之前可能用到靜態(tài)數(shù)據(jù)成員。例如:classAccout{{staticconstintnamesize=16;staticconstcharname[namesize];};constintAccout::namesize;constcharAccout::name[namesize]=”savingaccount”;3.3.1.3靜態(tài)數(shù)據(jù)成員的訪問student(inta,flo37類的成員函數(shù)中訪問:用靜態(tài)數(shù)據(jù)成員名直接訪問非成員函數(shù)中訪問public靜態(tài)數(shù)據(jù)成員:類名::靜態(tài)數(shù)據(jù)成員名對象.靜態(tài)數(shù)據(jù)成員名指向?qū)ο蟮闹羔?>靜態(tài)數(shù)據(jù)成員名例如:計數(shù)已創(chuàng)建對象的數(shù)目classData{intnum;floatscore;public:staticintobject;Data(inta,floatf):num(a),score(f){object++;}~Data(){object--;}};類的成員函數(shù)中訪問:用靜態(tài)數(shù)據(jù)成員名直接訪問383.3.2靜態(tài)成員函數(shù)
希望在產(chǎn)生對象之前訪問private靜態(tài)數(shù)據(jù)成員3.3.2.1聲明與定義在類內(nèi)普通成員函數(shù)聲明前加上static關(guān)鍵字,在類外定義前不需再加static。注意:靜態(tài)成員函數(shù)沒有this指針,不能訪問類的非靜態(tài)成員,只能訪問類的靜態(tài)數(shù)據(jù)成員或是調(diào)用其它靜態(tài)成員函數(shù)。3.3.2.2調(diào)用類名::靜態(tài)函數(shù)名(參數(shù)表);對象.靜態(tài)函數(shù)名(參數(shù)表);指向?qū)ο蟮闹羔?>靜態(tài)函數(shù)名(參數(shù)表);例如:classSmall{staticintobject;public:Small(){object++;}staticintget_n(){returnobject;}3.3.2靜態(tài)成員函數(shù)39~Small(){object--;}};intSmall::object=0;intmain(){intn;n=Small::get_n();//…}3.3.3全局、靜態(tài)局部類對象
3.3.3.1局部靜態(tài)類對象在函數(shù)或復(fù)合語句內(nèi),用static關(guān)鍵字定義的對象。例如:intfun(){staticData(1,89.0);return0;}代碼執(zhí)行過程中第一次遇到該對象定義時,構(gòu)造函數(shù)被調(diào)用,程序運行中僅調(diào)用一次;在程序運行結(jié)束前,調(diào)用析構(gòu)函數(shù),也只調(diào)用一次。例如:~Small(){o40classdemo{public:demo(){cout<<”objectconstructor\n”;}~demo(){cout<<”objectdestructor\n”}};voidfun(){staticdemod1;}intmain(){cout<<"mainstart\n";fun();cout<<"again\n";fun();輸出:mainstartcout<<"mainend\n";}objectconstructoragainmainendobjectdestructorclassdemo{413.3.3.2全局類對象在函數(shù)外定義的對象。構(gòu)造函數(shù)在main函數(shù)執(zhí)行前被調(diào)用,析構(gòu)函數(shù)在程序運行結(jié)束前調(diào)用。例如:classdemo{public: demo(){cout<<"objectconstructor\n";} ~demo(){cout<<"objectdestructor\n";}};intmain(){ cout<<"mainstart\n";cout<<"mainend\n";return0;}輸出:objectconstructorstaticdemod1;mainstartmainendobjectdestructor3.3.3.2全局類對象423.4友元3.4.1友元函數(shù)3.4.1.1友元函數(shù)的聲明允許一個類授權(quán)其它的函數(shù)或類訪問它的非公有成員。友元聲明以friend關(guān)鍵字開頭,只能出現(xiàn)在類的定義中。友元不是類的成員,不受訪問說明符的影響。一般將類中所有友元關(guān)系的聲明放在類頭之后。
¤語法:friend數(shù)據(jù)類型函數(shù)名(參數(shù)標(biāo));3.4.1.2友元函數(shù)的參數(shù)成員函數(shù)由對象調(diào)用,系統(tǒng)傳遞this指針使其可以訪問對象的成員。友元函數(shù)沒有this指針,要訪問對象的成員,必須將要訪問的對象作為參數(shù)傳遞。訪問類對象的成員必須加上對象名和成員訪問運算符。例如:classData{friendvoidget_val(Data&it,intn,floats);intnum;floatscore;3.4友元43public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}voidprint();};voidData::print(){cout<<num<<“\n”<<score<<“\n”;}voidset_val(Data&it,intn,floats){it.num=n;it.score=s;}intmain(){Datamydata;set_val(mydata,1,67.0);mydata.print();return0;}public:443.4.2友元類3.4.2.1友元類的聲明在類的定義體內(nèi)聲明
¤語法:friendclass類名;友元類的所有成員函數(shù)都可以訪問授權(quán)類的成員。友元關(guān)系是單向的,A是B的友元,但B不是A的友元。例如:classData{friendclassTeacher;intnum;floatscore;public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}voidprint();};3.4.2友元類45classTeacher{public:voidset_data(Data&it,intn,floats){it.num=n;it.score=s;}};intmain(){Datamydata;Teachertheteacher;theteacher.set_data(mydata,1,87.0);return0;}注意:Teacher類的定義應(yīng)在Data類之后。3.4.2.2類的成員函數(shù)作為友元函數(shù)若授權(quán)類的友元類中只有一個成員函數(shù)要訪問授權(quán)類的成員,可以只將該成員函數(shù)作為授權(quán)類的友元函數(shù)。classTeacher{46友元類必須在授權(quán)類之前定義,但是授權(quán)類要在友元類之前作前向聲明。只有當(dāng)一個類的定義已經(jīng)被看到時,其成員函數(shù)才能被聲明為另一個類的友元。例如:classData;//聲明classTeacher{public:voidset_data(Data&it,intn,floats){it.num=n;it.score=s;}};classData{friendvoidTeacher::set_data(Data&it,intn,floats);intnum;floatscore;public:Data(inta,floatf){num=a;score=f;}Data(){num=0;score=0.0;}};友元類必須在授權(quán)類之前定義,但是授權(quán)類要在友元類之前作47第4章運算符重載4.1算術(shù)運算符+、-可以對任意基本類型進行“+”運算,例如:3+4.7、5+’a’,c語言本身已經(jīng)重載了該運算符,所以它能夠用于int、float、double和其他內(nèi)部定義類型的變量.如果希望“+”運算可以應(yīng)用在類對象上,如:data1+data2,需要以函數(shù)的形式重新定義“+”運算執(zhí)行的行為,稱為運算符的重載。注意:①只能對用戶自定義的數(shù)據(jù)類型重載運算符,即運算符重載函數(shù)的參數(shù)至少有一個必須是類的對象或者是對類的對象的引用。②運算符重載實際是定義函數(shù),調(diào)用函數(shù)時實參不是出現(xiàn)在圓括號內(nèi),而是在運算符的旁邊,函數(shù)名是由關(guān)鍵字operator和其后要重載的運算符符號組成的。③重載不能改變運算符的優(yōu)先級、結(jié)合性。④重載不能改變運算符操作數(shù)的個數(shù)和運算符本身的含義。⑤不能創(chuàng)建新的運算符,只有現(xiàn)有的運算符才能被重載。
4.1.1作為普通(友元)函數(shù)重載
定義:數(shù)據(jù)類型operator+(參數(shù)表){}例如:classdemo{frienddemooperator+(demo&d1,demo&d2);第4章運算符重載48inta;floatb;public:demo(intx,floaty){a=x;b=y;}};demooperator+(demo&d1,demo&d2)//不能返回引用,局部對象temp//在函數(shù)結(jié)束后內(nèi)存空間被釋放{demotemp(0,0.0);temp.a=d1.a+d2.a;temp.b=d1.b+d2.b;returntemp;}或者:demooperator+(demo&d1,demo&d2){returndemo(d1.a+d2.a,d1.b+d2.b);}調(diào)用:對象+對象例如:inta;49demodemo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;//相當(dāng)于demo3=operator+(demo1,demo2);demooperator+(demo&d1,demo&d2)希望實現(xiàn)調(diào)用:對象+整數(shù)demooperator+(demo&d1,intx){demotemp(0,0.0);temp.a=d1.a+x;temp.b=d1.b+xreturntemp;}調(diào)用:demodemo1(2,3.2),demo2;demo2=demo1+5;//不能寫成demo2=5+demo1;demooperator+(demo&d1,intx)demodemo1(2,3.2),demo2(150希望實現(xiàn)調(diào)用:整數(shù)+對象demooperator+(intx,demo&d1){demotemp(0,0.0);temp.a=d1.a+x;temp.b=d1.b+xreturntemp;}調(diào)用:demodemo1(2,3.2),demo2;demo2=5+demo1;//相當(dāng)于demo2=operator+(5,demo1);4.1.2作為成員函數(shù)重載表示該類對象與另一個操作數(shù)進行運算。該類對象作為操作數(shù)1。成員函數(shù)將指向調(diào)用成員函數(shù)的類對象的this指針作為第一個參數(shù),所以重載運算符函數(shù)需要的參數(shù)個數(shù)為運算符的操作數(shù)個數(shù)-1。調(diào)用運算符重載函數(shù)時,運算符左側(cè)的操作數(shù)為調(diào)用成員函數(shù)的該類對象,右側(cè)的操作數(shù)為傳遞給成員函數(shù)的參數(shù)。例如:希望實現(xiàn)調(diào)用:整數(shù)+對象51classdemo{inta;floatb;public:demo(intx,floaty){a=x;b=y;}
demooperator+(demo&it);//相當(dāng)于demooperator+(demo*this,demo&it);};希望實現(xiàn)調(diào)用:對象+對象demodemo::operator+(demo&it){demotemp(0,0.0);temp.a=a+it.a;temp.b=b+it.b;returntemp;}例如:demodemo1(2,3.2),demo2(1,4.6),demo3;demo3=demo1+demo2;//相當(dāng)于demo3=demo1.operator+(demo2);classdemo{52希望實現(xiàn)調(diào)用:對象+整數(shù)demodemo::operator+(intx){demotemp(0,0.0);temp.a=a+xtemp.b=b+x;returntemp;}例如:demodemo1(2,3.2),demo2;demo2=demo1+5;//相當(dāng)于demo2=demo1.operator+(5);//不能寫成demo2=5+demo1;希望實現(xiàn)調(diào)用:整數(shù)+對象,不能定義成成員函數(shù)。如果運算符的左側(cè)操作數(shù)不是類類型而是其它類型,重載運算符函數(shù)只能作為友元函數(shù)。4.2運算符++、--
4.1.1作為普通(友元)函數(shù)重載前置運算符:希望實現(xiàn)調(diào)用:對象+整數(shù)53定義:數(shù)據(jù)類型operator++(參數(shù)表);例如:classdemo{frienddemo&operator++(demo&it);inta;floatb;public:demo(intx,floaty){a=x;b=y;}};demo&operator++(demo&it){it.a++;it.b++;returnit;}調(diào)用:++對象例如:demodemo1(2,3.2);++demo1;//相當(dāng)于operator++(demo1)定義:數(shù)據(jù)類型operator++(參數(shù)表);54后置運算符:需要增加一個額外的參數(shù)例如:demooperator++(demo&it,int){demotemp(it);//調(diào)用拷貝構(gòu)造函數(shù)it.a++;it.b++;returntemp;}調(diào)用:對象++例如:demodemo1(2,3.2);5+demo1++;//相當(dāng)于operator++(demo1,int)4.2.2作為成員函數(shù)
前置運算符:例如:classdemo{inta;floatb;后置運算符:需要增加一個額外的參數(shù)55public:demo(intx,floaty){a=x;b=y;}demo&operator++();};demo&demo::operator++(){a++;b++;return*this;}調(diào)用:demodemo1(2,3.2);++demo1;//相當(dāng)于demo1.operator++()后置運算符:增加一個額外的參數(shù)demodemo::operator++(int){demotemp=*this;//調(diào)用拷貝構(gòu)造函數(shù)a++;b++;returntemp;}public:56調(diào)用:demodemo1(2,3.2);5+demo1++;//相當(dāng)于demo1.operator++(int)4.3賦值運算符=的重載
運算符()、[]、->,或者任何賦值運算符重載函數(shù)必須聲明為類的一個成員函數(shù)。賦值運算符重載用于“=”兩側(cè)的對象都已經(jīng)存在時,一個類對象向該類的另一個對象賦值。一般在對象的數(shù)據(jù)成員是指針時用來進行深層復(fù)制。例如:demod1(1,4.2);//構(gòu)造函數(shù)demod2=d1;//拷貝構(gòu)造函數(shù)d3=d2;//賦值注意:①確保沒有將對象復(fù)制給它自身②重新使用被賦值對象中的資源或刪除它③從源對象上復(fù)制內(nèi)容到目的對象例如:classTstring{char*str;調(diào)用:demodemo1(2,3.2);57intlen;public:Tstring(constchar*p);~Tstring(){delete[]str;}Tstring(constTstring&source);Tstring&operator=(Tstring&it);};Tstring&Tstring::operator=(Tstring&it){if(this==&it)return*this;delete[]str;len=it.len;str=newchar[len]strcpy(str,it.str);return*this;}intlen;58賦值運算符重載也可以用于為一個類對象賦以不是該類類型的值。例如希望實現(xiàn)如下賦值:Tstringcar(“benz”);car=“bmw”;在類定義中增加成員函數(shù):Tstring&operator=(constchar*);Tstring&Tstring::operator=(constchar*cst){if(cst==0){len=0;delete[]str;str=0;}else{len=strlen(cst)+1;delete[]str;str=newchar[len]strcpy(str,it.cst);}
溫馨提示
- 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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 教科版 高一信息技術(shù) 必修1 第四單元 4.3 非數(shù)值計算 教學(xué)設(shè)計
- 產(chǎn)品收購合同范本
- 高中信息技術(shù)選修3教學(xué)設(shè)計-6.2 網(wǎng)站的制作與調(diào)試-浙教版
- 函數(shù)方程的思想-2024-2025學(xué)年初高中銜接數(shù)學(xué)教學(xué)設(shè)計
- 供應(yīng)鏈合同終止情況說明函范文
- Module 9 Unit 2 I want to go to Shanghai(教學(xué)設(shè)計)-2024-2025學(xué)年外研版(三起)英語六年級上冊
- 第一單元第1節(jié)感受萬物互聯(lián)的場景-第1課時 教學(xué)設(shè)計 2024-2025學(xué)年滬科版(2024)信息科技八年級上冊-
- 第五單元第2課時《大數(shù)據(jù)與人工智能初感受-關(guān)愛老人之智能養(yǎng)老項目規(guī)劃與項目實施》 教學(xué)設(shè)計 2023-2024學(xué)年教科版(2019)高中信息技術(shù)必修1
- 全國滇人版初中信息技術(shù)七年級上冊第一單元第1課《信息與信息的數(shù)字化》教學(xué)設(shè)計
- 事業(yè)單位聘用合同(32篇)
- 稅法最全課件完整版ppt教程整套教學(xué)講義(最新)
- 2022年南京信息職業(yè)技術(shù)學(xué)院職業(yè)適應(yīng)性測試模擬試題及答案解析
- 英語演講素材OfMiceandMen課件
- 廣東佛山祖廟導(dǎo)游詞
- 硬筆書法紙可打印
- 正丁烷的理化性質(zhì)及危險特性表
- 《朝天子詠喇叭》教學(xué)設(shè)計
- 《金融學(xué)基礎(chǔ)》實訓(xùn)手冊
- 稅收基礎(chǔ)知識考試題庫
- 1t燃氣蒸汽鍋爐用戶需求(URS)(共13頁)
- 廣發(fā)證券分支機構(gòu)人員招聘登記表
評論
0/150
提交評論