C-第11章運算符重載課件_第1頁
C-第11章運算符重載課件_第2頁
C-第11章運算符重載課件_第3頁
C-第11章運算符重載課件_第4頁
C-第11章運算符重載課件_第5頁
已閱讀5頁,還剩165頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載:字符串和數(shù)組對象簡介運算符重載使得系統(tǒng)的內(nèi)置運算符適用于類的對象之間的操作。提高程序的可讀性。運算符重載使得系統(tǒng)的內(nèi)置運算符適用于類的對象之間的操作。提高問題的提出希望某些運算符能夠?qū)φ麄€對象進行操作,而不是C中的簡單操作.例如:+運算符能夠?qū)崿F(xiàn)2個對象間的加。類A的對象a1、a2、a3,希望:a3=a1+a2;

即:分別把對象a1和a2的各個數(shù)據(jù)成員值對應(yīng)相加,然后賦給對象a3。問題的提出希望某些運算符能夠?qū)φ麄€對象進行操作,而不是C中的問題的提出把某些事交給系統(tǒng)去做,用戶只要知道相加就可提出運算符重載,擴充運算符的功能。即:對運算符進行重載定義,然后使用,由系統(tǒng)自動判斷究竟采用哪一個具體的運算符。增強了C++語言的可擴充性。問題的提出把某些事交給系統(tǒng)去做,用戶只要知道相加就可運算符重載的限制不是所有的運算符都能重載重載不能改變運算符的優(yōu)先級和結(jié)合性重載不能改變運算符的操作數(shù)個數(shù)不能創(chuàng)建新的運算符不能改變用于內(nèi)部類型對象時的含義用于用戶自定義類型對象,或者和內(nèi)部類型的對象混合使用運算符重載的限制不是所有的運算符都能重載可以重載的運算符+

-

*

/

%

^

&

|

~

!

=

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

==

!=

<=

>=

&&

||

++

--

->*

,

->

[]

()

new

delete

new[]

delete[]

.

.*

::

?:

sizeof

不能重載的運算符:可以重載的運算符+

-

運算符重載的實現(xiàn)方法

用普通函數(shù)實現(xiàn)用成員函數(shù)實現(xiàn)用友元函數(shù)實現(xiàn)運算符重載的實現(xiàn)方法用普通函數(shù)實現(xiàn)第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)實現(xiàn)運算符重載創(chuàng)建運算符函數(shù)運算符函數(shù)名為:

operator后接一個要重載的運算符。如:要重載“+”運算,函數(shù)名為operator+。重載“-”運算,函數(shù)名為operator-。參數(shù)表為要參加運算的對象,返回值為運算結(jié)果用普通函數(shù)實現(xiàn)運算符重載創(chuàng)建運算符函數(shù)運算符重載函數(shù)實例#include<iostream.h>classcomplex{public:intr,i;complex(intrr=0,intii=0){i=ii;r=rr;}};complexoperator+(complexa1,complexa2){complext;t.r=a1.r+a2.r;t.I=a1.i+a2.i;returnt;}voidmain(){complexa1(1,2),a2(3,4),b;b=a1+a2;cout<<b.r<<b.i;}運算符重載函數(shù)實例#include<iostream.h>重載成普通函數(shù)的缺陷運算符重載通常要對類的私有數(shù)據(jù)成員作操作。如果用普通函數(shù)重載,則需要通過公有的方法訪問私有的數(shù)據(jù)成員,運算速度較慢,或?qū)⑺械臄?shù)據(jù)成員都設(shè)為公有,直接訪問這些數(shù)據(jù)成員,這樣將違反類的封裝。重載成普通函數(shù)的缺陷運算符重載通常要對類的私有數(shù)據(jù)成員作操作第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載:字符串和數(shù)組對象簡介友元運算符函數(shù)把運算符函數(shù)定義成某個類的友元函數(shù),稱為友元運算符函數(shù)。友元函數(shù)在類內(nèi)部的聲明

friendtypeoperator@(參數(shù)表);友元函數(shù)的定義:與一般函數(shù)相同typeoperator@(參數(shù)表){//函數(shù)體}友元運算符函數(shù)把運算符函數(shù)定義成某個類的友元函數(shù),稱為友元運雙目運算符重載友元運算符函數(shù)必須有兩個參數(shù)例:二元加操作符重載為友元函數(shù)#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}A(){x=0;y=0;}friendAoperator+(constA&a,constA&b);voidshow(){cout<<"x="<<x<<"y="<<y<<endl;}};Aoperator+(constA&a,constA&b){returnA(a.x+b.x,a.y+b.y);}voidmain(){Aa1(5,55),a2(6,66),a3;a3=a1+a2;//調(diào)用操作符重載函數(shù):oprator+(a1,a2)a3.show();}x=11y=121雙目運算符重載x=11y=121單目運算符重載友元運算符有一個參數(shù)例:一元減操作符重載為友元函數(shù)#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}A(){x=0;y=0;}

friendAoperator-(constA&a);voidshow(){cout<<"x="<<x<<"y="<<y<<endl;}};Aoperator-(constA&a){returnA(-a.x,-a.y);}voidmain(){Aa1(5,55);a1=-a1;//調(diào)用操作符重載函數(shù):operator+(a1)a1.show();}x=-5y=-55單目運算符重載友元運算符有一個參數(shù)x=-5y=-55第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載:字符串和數(shù)組對象簡介成員運算符函數(shù)運算符重載通常作用在一個類上,因此可定義為類的成員函數(shù)或友元函數(shù)。成員運算符函數(shù)的聲明classX{//…

typeoperator@(參數(shù)表)//…}成員運算符函數(shù)的定義

typeX::operator@(參數(shù)表){//函數(shù)體}成員運算符函數(shù)運算符重載通常作用在一個類上,因此可定義為類的雙目運算符重載成員運算符只需要一個參數(shù),作為運算符的右操作數(shù),當前對象作為左操作數(shù)。例1:二元加操作符重載為成員函數(shù)。#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}A(){x=0;y=0;}

Aoperator+(Ab){Atmp; tmp.x=x+b.x;tmp.y=y+b.y;returntmp;}voidshow(){cout<<"x="<<x<<"y="<<y<<endl;}};voidmain(){Aa1(5,55),a2(6,66),a3;a3=a1+a2;//a3=a1.operator+(a2);a3.show();}x=11y=121雙目運算符重載成員運算符只需要一個參數(shù),作為運算符的右操作數(shù)單目運算符重載成員運算符無參數(shù)例:一元減操作符重載為成員函數(shù)#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}A(){x=0;y=0;}

Aoperator-(){returnA(-x,-y);}voidshow(){cout<<"x="<<x<<“y="<<y<<endl;}};voidmain(){Aa1(5,55);a1=-a1;//調(diào)用操作符重載函數(shù):a1=a1.operator-()a1.show();}/*執(zhí)行結(jié)果:x=-5y=-55*/單目運算符重載成員運算符無參數(shù)成員運算符函數(shù)與友元運算符函數(shù)的比較成員運算符函數(shù)比友元運算符函數(shù)少一個參數(shù)。除=、()、[]、->這4種操作符必須重載成成員函數(shù)外,其他操作符重載成友元函數(shù)較好。例,a是類A的一個對象,對于表達式:27.5+a對友元函數(shù)不存在問題:operator+(A(27.5),a)但是,對成員函數(shù)存在問題:(27.5).operator+(a)//非法:27.5不是一個對象,無this指針。成員運算符函數(shù)與友元運算符函數(shù)的比較成員運算符函數(shù)比友元運算成員運算符函數(shù)與友元運算符函數(shù)的比較cont.成員運算符函數(shù)和友元運算符函數(shù)都可用習慣方式調(diào)用,也可用專用方式調(diào)用。習慣方式友元運算符調(diào)用方式成員運算符調(diào)用方式a+boperator+(a,b)a.operator+(b)-aoperator-(a)a.operator-()成員運算符函數(shù)與友元運算符函數(shù)的比較cont.成員運算第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載:字符串和數(shù)組對象簡介典型的運算符重載++和--的重載=的重載類型轉(zhuǎn)換典型的運算符重載++和--的重載“++”和“--”重載++、--:是一元操作符但是,可以是前綴或后綴。所以,重載時有所不同。區(qū)分方法:前綴:一元操作符。后綴:二元操作符?!?+”和“--”重載++、--:是一元操作符“++”和“--”重載cont.成員函數(shù)重載++ob重載為:ob.operator++()ob--重載為:ob.operator--(int)友元函數(shù)重載++ob重載為:operator++(X&ob)ob--重載為:operator--(X&ob,int)調(diào)用時,參數(shù)int一般傳遞給值0。“++”和“--”重載cont.成員函數(shù)重載++和--操作符重載成成員函數(shù)

#include<iostream.h>classCounter{unsignedvalue;public:Counter(intv=0){value=v;}

Counteroperator++(){value++;cout<<"1..."<<value<<"";return*this;}

Counteroperator++(int){Countert;cout<<"2..."<<value<<"";t.value=value++;returnt;}voiddisplay(){cout<<value<<endl;}};voidmain(){Countera(11),b(22),c;++a;//自動調(diào)用operator++()a.display();c=b++;//自動調(diào)用operator++(int)b.display();c.display();}1...12122...222322*/++和--操作符重載成成員函數(shù)#include<iostr++和--操作符重載成友元函數(shù)

#include<iostream.h>classCounter{unsignedvalue;public:Counter(intv=0){value=v;}

friendCounteroperator++(Counter&);friendCounteroperator++(Counter&,int);voiddisplay()const{cout<<value<<endl;}};Counteroperator++(Counter&cc){cc.value++;cout<<"1..."<<cc.value<<"";returncc;}Counteroperator++(Counter&cc,int){Countert;cout<<"2..."<<cc.value<<"";t.value=cc.value++;returnt;}voidmain(){Countera(11),b(22),c;

++a;//自動調(diào)用operator++(Counter&)a.display();c=b++;//自動調(diào)用operator++(Counter&,int)b.display();c.display();}1...12122...222322*/++和--操作符重載成友元函數(shù)#include<iostr運算符重載實例試設(shè)計一個類,用來表示大于longint的數(shù)字設(shè)想:用一個由數(shù)字組成的字符串來表示數(shù)據(jù)。如允許的最大長度為128位,則字符數(shù)組的長度為128。如數(shù)字123,可表示為127126…4321000000123運算符重載實例試設(shè)計一個類,用來表示大于longint類的定義classlonglong{chars[128];public:longlong(constchar*s1);longlong(); friendlonglongoperator+(constlonglong&p1,constlonglong&p2); friendlonglongoperator+(constlonglong&p1,constint&p2); friendlonglongoperator+(constint&p2,constlonglong&p1); friendlonglongoperator-(constlonglong&p1,constlonglong&p2); friendlonglongoperator-(constlonglong&p1,constint&p2); friendlonglongoperator-(constint&p2,constlonglong&p1); friendlonglongoperator*(constlonglong&p1,constlonglong&p2); friendlonglongoperator*(constlonglong&p1,constint&p2); friendlonglongoperator*(constint&p2,constlonglong&p1); friendlonglongoperator/(constlonglong&p1,constlonglong&p2); friendlonglongoperator/(constlonglong&p1,constint&p2); friendlonglongoperator%(constlonglong&p1,constlonglong&p2); friendlonglongoperator%(constlonglong&p1,constint&p2); voidshow();};類的定義classlonglong構(gòu)造函數(shù)定義longlong(constchar*s1){inti=strlen(s1)-1,j=0; while(i>=0){if(s1[i]>'9'||s1[i]<'0') {cout<<"seterror";i=-1;} else{s[j]=s1[i];--i;++j;}} for(;j<128;++j)s[j]='0'; }longlong(){for(inti=0;i<128;++i)s[i]='0';}構(gòu)造函數(shù)定義longlong(constchar*s1加法運算定義longlongoperator+(constlonglong&p1,constlonglong&p2){longlongt;inti,j=0;for(i=0;i<128;++i){t.s[i]=p1.s[i]-'0‘+p2.s[i]-'0‘+j;if(t.s[i]>10)j=t.s[i]/10;elsej=0; t.s[i]=t.s[i]%10+'0';}returnt;}加法運算定義longlongoperator+(const加法運算定義longlongoperator+(constlonglong&p1,constint&p2){longlongt;inti,j=0;for(i=0;i<128;++i){t.s[i]=p1.s[i]-'0‘+p2%10+j;p2=p2/10;if(t.s[i]>10)j=t.s[i]/10;elsej=0; t.s[i]=t.s[i]%10+'0';}returnt;}加法運算定義longlongoperator+(const顯示函數(shù)定義voidshow(){inti=127;while(s[i]==‘0’)--i;//去掉高位0while(i>=0){cout<<s[i];--i;} cout<<endl;}顯示函數(shù)定義voidshow()測試程序voidmain(){longlonga("123"),b("345"),c;c=a+b;c.show();c=a+5;c.show();}648128測試程序voidmain()648典型的運算符重載++和--的重載=的重載類型轉(zhuǎn)換典型的運算符重載++和--的重載賦值運算符“=”的重載對任一類,如果用戶沒有自定義賦值運算符函數(shù),那么系統(tǒng)為其生成一個缺省的賦值運算符函數(shù),在對應(yīng)成員間賦值。

X&X::operator=(constX&source){//成員間對應(yīng)賦值}一旦創(chuàng)建了對象x1,x2,可以用x1=x2賦值。賦值運算符“=”的重載對任一類,如果用戶沒有自定義賦值運算符賦值運算符“=”的重載有時,使用缺省運算符函數(shù)會產(chǎn)生錯誤。如:#include<iostream.h>#include<string.h>Classstring{char*ptr;public:string(char*s){ptr=newchar[strlen(s)+1];strcpy(ptr,s);}~string(){deleteptr;}voidprint(){cout<<ptr<<endl;}};voidmain(){stringp1(“chen”);{stringp2(““);p2=p1;cout<<“p2:”;p2.print();}cout<<“p1:”;p1.print();}/*p1指向的空間會丟失*/賦值運算符“=”的重載有時,使用缺省運算符函數(shù)會產(chǎn)生錯誤。如解決方法顯式定義一個賦值運算符重載函數(shù),使p1和p2有各自的存儲空間,實現(xiàn)方法如下:string&string::operator=(conststring&s){if(this==&s)return*this;deleteptr;ptr=newchar[strlen(s.ptr)+1];strcpy(ptr,s.ptr);return*this;}解決方法顯式定義一個賦值運算符重載函數(shù),使p1和p2有各自的#include<iostream.h>#include<string.h>classstring{char*ptr;public:string(char*s){ptr=newchar[strlen(s)+1];strcpy(ptr,s);} ~string(){deleteptr;} voidprint(){cout<<ptr<<endl;} string&operator=(conststring&);};string&string::operator=(conststring&s){if(this==&s)return*this;deleteptr;ptr=newchar[strlen(s.ptr)+1];strcpy(ptr,s.ptr);return*this;}voidmain(){stringp1("chen");{stringp2(""); p2=p1;cout<<"p2:";p2.print();}cout<<"p1:";p1.print();}#include<iostream.h>賦值運算符“=”重載的說明類的賦值運算符“=”只能重載為成員函數(shù),而不能把它重載為友元函數(shù)。當重載為成員函數(shù)時,該函數(shù)只有一個參數(shù)。p1=p2相當于p1.operator=(p2)。如用友元函數(shù),必須有兩個參數(shù)operator=(p1,p2),如果p1為一常數(shù),則會出錯。類的賦值運算符“=”可以被重載,但重載的運算符函數(shù)operator=()不能被繼承。賦值運算符“=”重載的說明類的賦值運算符“=”只能重載為成Longlong類型中重載賦值運算符Longlong&operator=(constchar*s1){inti=strlen(s1)-1,j=0; while(i>=0){if(s1[i]>'9'||s1[i]<'0') {cout<<"seterror";i=-1;} else{s[j]=s1[i];--i;++j;}} for(;j<128;++j)s[j]='0'; }在程序中可用:a=“1234567890123”;Longlong類型中重載賦值運算符Longlong&賦值運算符重載帶來的問題在上面的賦值運算符重載函數(shù)中,函數(shù)的參數(shù)是char*,這樣會使得c=a+b這樣的運算不能執(zhí)行,因為表達式的右邊是一個對象而不是字符串。解決方法:可以用函數(shù)重載再寫一個賦值函數(shù),他的參數(shù)是對象賦值運算符重載帶來的問題在上面的賦值運算符重載函數(shù)中,函數(shù)的典型的運算符重載++和--的重載=的重載類型轉(zhuǎn)換典型的運算符重載++和--的重載類型轉(zhuǎn)換--系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換隱式類型轉(zhuǎn)換

※賦值時

※運算時顯式類型轉(zhuǎn)換※強制轉(zhuǎn)換法:(類型名)表達式※函數(shù)法:類型名(表達式)類型轉(zhuǎn)換--系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換隱式類型轉(zhuǎn)換類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換通過構(gòu)造函數(shù)進行類型轉(zhuǎn)換#include<iostream.h>classexample{intnum;public:example(intn){num=n;}voidprint(){cout<<num<<endl;}};voidmain(){examplex=6;//通過構(gòu)造函數(shù)進行類型轉(zhuǎn)換x.print();}類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換通過構(gòu)造函數(shù)進行類型類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換通過類型轉(zhuǎn)換函數(shù)進行類型轉(zhuǎn)換聲明格式:operator類型標識符()const;定義格式:類名::operator類型標識符()const{…;return類型標識符指定的變量;}說明:類類型轉(zhuǎn)換函數(shù):無函數(shù)返回類型,無參數(shù)。因為,總是轉(zhuǎn)換成“類型標識符”所指出的類型,且被轉(zhuǎn)換的總是本類的一個對象(由this指針指出)。類型轉(zhuǎn)換函數(shù)只能定義為非靜態(tài)的成員函數(shù)類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換通過類型轉(zhuǎn)換函數(shù)進行類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換classCounter{intv1;charv2;public:Counter(intv=0,charvv='?'){v1=v;v2=vv;}

operatorchar(){returnv2;}

operatorint(){returnv1;}voiddisplay(){cout<<"Counter:v1="<<v1<<"v2="<<v2<<endl;}friendCounterfn(Counterc);};Counterfn(Counterc){c.v1=c.v1*2;returnc;}voidmain(){charx;inty;Counterc1(64,'%'),c2(99,'@');c1.display();c2.display();c2=fn(12345);//實參12345通過構(gòu)造函數(shù)//Counter(intv=0,charvv='?')轉(zhuǎn)換成Counter類型c2.display();x=c1;//通過成員函數(shù)轉(zhuǎn)換成char型y=c1;//通過成員函數(shù)轉(zhuǎn)換成int型cout<<x<<""<<y<<endl;}Counter:v1=64v2=%Counter:v1=99v2=@Counter:v1=24690v2=?%64

類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換classCoun類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換運算符重載與類型轉(zhuǎn)換:在某些情況下,用戶希望將類對象與基本數(shù)據(jù)類型進行運算,這可以通過運算符重載來完成。如要實現(xiàn)復(fù)數(shù)與整型數(shù)相加:類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換運算符重載與類型轉(zhuǎn)換類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換運算符重載與類型轉(zhuǎn)換:在某些情況下,用戶希望將類對象與基本數(shù)據(jù)類型進行運算,這可以通過運算符重載來完成。如要實現(xiàn)復(fù)數(shù)與整型數(shù)相加:類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換運算符重載與類型轉(zhuǎn)換類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換classcomplex{floatreal,imag;public:complex(floatr=0,floati=0){real=r;imag=i;}

friendcomplexoperator+(intx,complexy) {complextmp; tmp.real=x+y.real;tmp.imag=y.imag;returntmp;} voidprint(){cout<<real<<","<<imag<<endl;} };voidmain(){complexob1(10.5,20.5),ob2;intx=100;ob1.print();ob2=x+ob1;//整型變量與類對象相加ob2.print();}/*輸出10.5,20.5110.5,20.5*/類型轉(zhuǎn)換—類類型與系統(tǒng)預(yù)定義類型間的轉(zhuǎn)換classcomp第11章運算符重載簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載簡介輸入輸出流重載能否使類的對象也能像內(nèi)置類型一樣直接用cin和cout完成輸入輸出?方法是重載流插入<<和流提取>><<和>>的重載是使用友元函數(shù)輸入輸出流重載能否使類的對象也能像內(nèi)置類型一樣直接用cin和重載“<<”定義格式:ostream&operator<<(ostream&stream,constclass_name&obj){//操作代碼returnstream;}重載“<<”定義格式:重載“<<”實例原有的實現(xiàn)方法#include<iostream.h>classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}voidshow(){cout<<"x=“<<x<<"y=“<<y<<endl;}};voidmain(){Aa1(5,55);a1.show();}/*執(zhí)行結(jié)果:x=5y=55*/重載“<<”實例原有的實現(xiàn)方法重載“<<”實例現(xiàn)在的實現(xiàn)方法classA{intx,y;public:A(intxx,intyy):x(xx),y(yy){}

friendostream&operator<<(ostream&op,constA&a);};ostream&operator<<(ostream&op,constA&a){op<<"x=“<<a.x<<"y=“<<a.y<<endl;returnop;}voidmain(){Aa1(5,55);cout<<a1;}/*執(zhí)行結(jié)果:x=5y=55*/重載“<<”實例現(xiàn)在的實現(xiàn)方法Longlong類型的輸出ostream&operator<<(ostream&ss,constlonglong&p){inti=127;while(p.s[i]=='0')--i;//去掉高位0while(i>=0){ss<<p.s[i];--i;} ss<<endl;returnss;}如定義了longlong類的對象a,在使用中可用cout<<a來輸出Longlong類型的輸出ostream&operator重載“>>”與重載輸出操作符類似。其定義格式為:

istream&operator>>(istream&stream,class_name&obj){//操作代碼returnstream;}重載“>>”與重載輸出操作符類似。其定義格式為:第11章運算符重載簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載簡介數(shù)組的缺陷數(shù)組無越界檢查不能一次輸入或輸出整個數(shù)組不能比較兩個數(shù)組數(shù)組作為參數(shù)傳遞時必須有一個額外的參數(shù)表示數(shù)組的大小數(shù)組不能直接賦值數(shù)組的缺陷數(shù)組無越界檢查Array類設(shè)計一個整型數(shù)組的改進版保證數(shù)組不越界允許將一個數(shù)組賦給另一個數(shù)組數(shù)組對象自動知道數(shù)組的大小可以用==和!=直接比較兩個數(shù)組Array類設(shè)計一個整型數(shù)組的改進版實現(xiàn)array類的關(guān)鍵--下標運算符“[]”的重載將某一函數(shù)的執(zhí)行表示成數(shù)組中的下標形式。下標運算符重載時,只能顯式聲明一個參數(shù),即下標值。其格式為

數(shù)組類型&operator[](inti)只能重載為成員函數(shù)實現(xiàn)array類的關(guān)鍵--下標運算符“[]”的重載將某一函classArray{

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

friendistream&operator>>(istream&,Array&);

intsize;//sizeofthearray

int*ptr;//pointertofirstelementofarray

staticintarrayCount;

//#ofArraysinstantiatedpublic:

Array(int=10);

//defaultconstructor

Array(constArray&);

//copyconstructor

~Array();

//destructor

Array類的定義classArray{

friendostre

intgetSize()const;

//returnsize

constArray&operator=(constArray&);//assignarrays

booloperator==(constArray&)const;

//compareequal

//Determineiftwoarraysarenotequaland

//returntrue,otherwisereturnfalse(usesoperator==).

booloperator!=(constArray&right)const

{return!(*this==right);}

int&operator[](int);

//subscriptoperator

constint&operator[](int)const;

//subscriptoperator

staticintgetArrayCount()

//Returncountof

{return

arrayCount;}

//arraysinstantiated.

};

intgetSize()const;

Array類的實現(xiàn)—構(gòu)造函數(shù)//InitializestaticdatamemberatfilescopeintArray::arrayCount=0;

//noobjectsyet//DefaultconstructorforclassArray(defaultsize10)Array::Array(intarraySize){

size=(arraySize>0?arraySize:10);

ptr=newint[size];//createspaceforarray

assert(ptr!=0);

//terminateifmemorynotallocated

++arrayCount;

//countonemoreobject

for(inti=0;i<size;i++)

ptr[i]=0;

//initializearray}Array類的實現(xiàn)—構(gòu)造函數(shù)//Initializest拷貝構(gòu)造函數(shù)//CopyconstructorforclassArray//mustreceiveareferencetopreventinfiniterecursion

Array::Array(constArray&init):size(init.size)

{

ptr=newint[size];//createspaceforarray

assert(ptr!=0);

//terminateifmemorynotallocated

++arrayCount;

//countonemoreobject

for(inti=0;i<size;i++)

ptr[i]

=init.ptr[i];

//copyinitintoobject

}拷貝構(gòu)造函數(shù)//Copyconstructorfor1每個類只有一個析構(gòu)函數(shù)和一個賦值函數(shù),但可以有多個構(gòu)造函數(shù)(包括一個拷貝構(gòu)造函數(shù),其它的稱為普通構(gòu)造函數(shù))。2對于任意一個類A,如果不想編寫上述函數(shù),C++編譯器將自動為A產(chǎn)生四個缺省的函數(shù):對象復(fù)制可以將一個對象的所有數(shù)據(jù)成員的值賦給同類的另一個對象,如果對象的數(shù)據(jù)成員中不存在指針,則沒有問題,但如果其中含有指針,則這種方式只是簡單地把指針所指向的內(nèi)容的地址復(fù)制過來,并沒有復(fù)制其所指的內(nèi)容。這可能并不是用戶所期望的。這要通過自定義的復(fù)制策略來實現(xiàn):拷貝構(gòu)造函數(shù)和重載運算符“=”。1每個類只有一個析構(gòu)函數(shù)和一個賦值函數(shù),但可以有多個構(gòu)造對象的復(fù)制在C++中,下面三種對象需要拷貝構(gòu)造函數(shù)

1一個對象以值傳遞的方式傳入函數(shù)體

2一個對象以值傳遞的方式從函數(shù)返回

3一個對象需要通過另外一個對象進行初始化拷貝構(gòu)造函數(shù)的形式A(constA&)

對象的復(fù)制在C++中,下面三種對象需要拷貝構(gòu)造函數(shù)

1拷貝構(gòu)造函數(shù)和賦值函數(shù)拷貝構(gòu)造函數(shù)是在對象創(chuàng)建時調(diào)用的,而賦值函數(shù)只能被已經(jīng)存在了的對象調(diào)用。stringa("Hello");stringb("world");stringc=a//調(diào)用了拷貝構(gòu)造函數(shù),最好寫成c(a)c=b//調(diào)用了賦值函數(shù)

拷貝構(gòu)造函數(shù)和賦值函數(shù)拷貝構(gòu)造函數(shù)是在對象創(chuàng)建時調(diào)用析構(gòu)函數(shù)//DestructorforclassArray

Array::~Array()

{

delete[]ptr;

//reclaimspaceforarray

--arrayCount;

//onefewerobjects

}

//Getthesizeofthearray

intArray::getSize()const{returnsize;}析構(gòu)函數(shù)//Destructorforclass=運算符重載//constreturnavoids:(al=a2)=a3

constArray&Array::operator=(constArray&right)

{

if(&right!=this){

if(size!=right.size){

delete[]ptr;

//reclaimspace

size=right.size;

//resizethisobject

ptr=newint[size];

assert(ptr!=0);

//terminateifnotallocated

}

for(inti=0;i<size;i++)ptr[i]=right.ptr[i];

}

return*this;

//enablesx=y=z;

}=運算符重載//constreturnavoids:判相等boolArray::oprator==(constArray&right)const

{

if(size!=right.size)

returnfalse;

//arraysofdifferentsizes

for(inti=0;i<size;i++)

if(ptr[i]

!=right.ptr[i])

returnfalse;//arraysarenotequal

returntrue;

//arraysareequal

}

判相等boolArray::oprator==(cons重載[]--檢查下標是否越界int&Array::operator[](intsubscript)

{

assert(0<=subscript&&subscript<size);

returnptr[subscript];//referencereturn

}

constint&Array::operator[](intsubscript)const

{

assert(0<=subscript&&subscript<size);

returnptr[subscript];//constreferencereturn

}重載[]--檢查下標是否越界int&Array::ope輸入輸出重載istream&operator>>(istream&input,Array&a)

{

for(inti=0;i<a.size;i++)

input>>a.ptr[i];

returninput;

//enablescin>>x>>y;

}

輸入輸出重載istream&operator>>(istostream&operator<<(ostream&output,constArray&a)

{

inti;

for(i=0;i<a.size;i++){

output<<setw(12)<<a.ptr[i];

if((i+1)%4==0)//4numbersperrowofoutput

output<<endl;

}

if(i%4!=0)

output<<endl;

returnoutput;

//enablescout<<~<<y;

}ostream&operator<<(ostream&Array類的使用intmain()

{

//noobjectsyet

cout<<"#ofarraysinstantiated="

<<Array::getArrayCount()<<'\n';

//createtwoarraysandprintArraycount

Arrayintegers1(7),integers2;

cout<<"#ofarraysinstantiated="

<<Array::getArrayCount()<<"\n\n";#ofarraysinstantiated=0

#ofarraysinstantiated

2Array類的使用intmain()

{

///printintegerslsizeandcontents

cout<<"Sizeofarrayintegers1is"

<<integers1.getSize()

<<"\nArrayafterinitialization:\n"

<<integersl<<'\n';

//printintegers2sizeandcontents

cout<<"Sizeofarrayintegers2is"

<<

integers2.getSize()

<<"\nArrayafterinitialization:\n"

<<integers2<<'\n';Sizeofarrayintegerslis7

Arrayafterinitialization:

0

0

0

0

0

0

0

0

Sizeofarrayintegers2is10

Arrayafterinitialization:

0

0

0

0

0

0

0

0

0

0//printintegerslsizeandco//inputandprintintegerslandintegers2

cout<<"Input17integers:\n";

cin>>integers1>>integers2;

cout<<"Afterinput,thearrayscontain:\n"

<<"integersl:\n"<<infegers1

<<"integers2:\n"<<integers2<<'\n';

//useoverloadedinequality(!=)operator

cout<<"Evaluating:integers1!=integers2\n";

if(integers1!=integers2)

cout<<"Theyarenotequal\n";

Input17integers:

1234567891011121314151617

Afterinput,thearrayscontain:

integersl:

1

2

3

4

5

6

7

integers2:

8

9

10

11

12

13

14

15

16

17

Evaluating:integers1!=integers2

Theyarenotequal//inputandprintintegersla//createarrayintegers3usingintegers1asan

//initlizer;printsizeandcontents

Arrayintegers3(integers1);

cout<<"\nSizeofarrayintegers3is"

<<integers3.getSize()

<<"\nArrayafterinitialization:\n"

<<integers3<<'\n';Sizeofarrayintegers3is7

Arrayafterinitialization:

1

2

3

4

5

6

7//createarrayintegers3usin//useoverloadedassignment(=)operator

cout<<"Assigningintegers2tointegers1:\n";

integers1=integers2;

cout<<"integersl:\n"<<integers1

<<"integers2:\n"<<integers2<<'\n';

//useoverloadedequality(==)operator

cout<<"Evaluating:integers1==integers2\n";

if(integers1==integers2)

cout<<"Theyareequal\n\n";Assigningintegers2tointeqersl:

integersl:

8

9

10

11

12

13

14

15

16

17

integers2:

8

9

10

11

12

13

14

15

16

17

Evaluating:integersl==integers2

Theyareequal//useoverloadedassignment(//useoverloadedsubscriptoperator//tocreatervalue

cout<<"integers1[5]is"<<integers1[5]<<'\n';

//useoverloadedsubscriptoperator//tocreatelvalue

cout<<"Assigning1000tointegers1[5]\n";

<<

integers1[5]=1000;

cout<<"integers1:\n"<<integers1<<'\n';integersl[5]is=13

Assigning1000tointegersl[5]

integersl:

8

9

10

11

12

1000

14

15

16

17//useoverloadedsubscriptop//attempttouseoutofrangesubscript

cout<<“Attempttoassign1000tointegersl[15]”<<endl;

integers1[15]=1000;

//ERROR:outofrange

return0;

}Attempttoassign1000tointegersl[15]

Assertionfailed:0<=subscript&&subscript<size,

fileArrayl.cpp,line87

abnormalprogramtermination//attempttouseoutofrange第11章運算符重載簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載簡介實例研究:string類在C語言中,string不是內(nèi)置類型,不能用系統(tǒng)預(yù)制的運算符來進行操作。所有的操作都是通過字符串函數(shù)來實現(xiàn)目的:創(chuàng)建一種字符串類型,使之可以用預(yù)制的運算符來操作字符串。手段:通過運算符重載具體內(nèi)容見教材P459實例研究:string類在C語言中,string不是內(nèi)置類型類String的拷貝構(gòu)造函數(shù)與賦值函數(shù)

//拷貝構(gòu)造函數(shù)

String::String(constString&other)

{

//允許操作other的私有成員m_data

intlength=strlen(other.m_data);

m_data=newchar[length+1];

strcpy(m_data,other.m_data);

}

//賦值函數(shù)

String&String::operate=(constString&other)

{

//(1)檢查自賦值

if(this==&other)

return*this;

//(2)釋放原有的內(nèi)存資源

delete[]m_data;

//(3)分配新的內(nèi)存資源,并復(fù)制內(nèi)容

intlength=strlen(other.m_data);

m_data=newchar[length+1];

strcpy(m_data,other.m_data);

//(4)返回本對象的引用

return*this;

}

類String的拷貝構(gòu)造函數(shù)與賦值函數(shù)

//拷貝構(gòu)造函小結(jié)運算符重載的注意事項如果左邊的操作數(shù)必須是一個不同的類的對象,該運算符必須作為一個非成員函數(shù)來實現(xiàn)轉(zhuǎn)換構(gòu)造函數(shù)是帶有一個參數(shù)的構(gòu)造函數(shù)小結(jié)運算符重載的注意事項第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載:字符串和數(shù)組對象簡介運算符重載使得系統(tǒng)的內(nèi)置運算符適用于類的對象之間的操作。提高程序的可讀性。運算符重載使得系統(tǒng)的內(nèi)置運算符適用于類的對象之間的操作。提高問題的提出希望某些運算符能夠?qū)φ麄€對象進行操作,而不是C中的簡單操作.例如:+運算符能夠?qū)崿F(xiàn)2個對象間的加。類A的對象a1、a2、a3,希望:a3=a1+a2;

即:分別把對象a1和a2的各個數(shù)據(jù)成員值對應(yīng)相加,然后賦給對象a3。問題的提出希望某些運算符能夠?qū)φ麄€對象進行操作,而不是C中的問題的提出把某些事交給系統(tǒng)去做,用戶只要知道相加就可提出運算符重載,擴充運算符的功能。即:對運算符進行重載定義,然后使用,由系統(tǒng)自動判斷究竟采用哪一個具體的運算符。增強了C++語言的可擴充性。問題的提出把某些事交給系統(tǒng)去做,用戶只要知道相加就可運算符重載的限制不是所有的運算符都能重載重載不能改變運算符的優(yōu)先級和結(jié)合性重載不能改變運算符的操作數(shù)個數(shù)不能創(chuàng)建新的運算符不能改變用于內(nèi)部類型對象時的含義用于用戶自定義類型對象,或者和內(nèi)部類型的對象混合使用運算符重載的限制不是所有的運算符都能重載可以重載的運算符+

-

*

/

%

^

&

|

~

!

=

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

==

!=

<=

>=

&&

||

++

--

->*

,

->

[]

()

new

delete

new[]

delete[]

.

.*

::

?:

sizeof

不能重載的運算符:可以重載的運算符+

-

運算符重載的實現(xiàn)方法

用普通函數(shù)實現(xiàn)用成員函數(shù)實現(xiàn)用友元函數(shù)實現(xiàn)運算符重載的實現(xiàn)方法用普通函數(shù)實現(xiàn)第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)重載用友員函數(shù)重載用成員函數(shù)重載典型的運算符重載輸入輸出重載實例研究:array類實例研究:string類第11章運算符重載:字符串和數(shù)組對象簡介用普通函數(shù)實現(xiàn)運算符重載創(chuàng)建運算符函數(shù)運算符函數(shù)名為:

operator后接一個要重載的運算符。如:要重載“+”運算,函數(shù)名為operator+。重載“-”運算,函數(shù)名為operator-。參數(shù)表為要參加運算的對象,返回值為運算結(jié)果用普通函數(shù)實現(xiàn)運算符重載創(chuàng)建運算符函數(shù)運算符重載函數(shù)實例#include<iostream.h>classcomplex{publ

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論