




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
OperatorOverloading
Zhao,Qingjie
zhaoqj@
BeijingInstituteofTechnology
FunctionOverloading
Differentfunctionshavethesamename(polymorphism)
InC++,afunctionisidentifiednotonlybythename,butalsobythenumberandthetypesofitsparametersandthekeyword,(const).
FunctionOverloading-Examples
voidswap(unsignedlong&,unsignedlong&);voidswap(double&,double&);
voidswap(char&,char&);voidswap(Point&,Point&);
Theyaredifferentfunctions!
Functionswiththesamenameshouldhavesimilarfunction.
Whyoperatorsneedoverloading?
classcomplex
{
public:
complex(doublex=0,doubley=0)
{re=x; im=y; }
voidmain()
{
complexc,c1,c2(5.5,2);c=c1.Add(c2);
constcomplexAdd(constcomplex&c)}
{
doublet1=re+c.re;doublet2=im+c.im;returncomplex(t1,t2);
}
Infact,wehopetowriteitlikethis:
c=c1+c2;
UseOperatorOverloading
private:
doublere,im;
};
Warning&reassurance
Operatoroverloadingisanotherwayofcallingafunction.
Itisforthecodeinvolvingyourclasseasiertowriteandespeciallyeasiertoread.
Alltheoperatorsusedinexpressionsthatcontainonlybuilt-indatatypescannotbechanged.Onlyanexpressioncontainingauser-definedtypecanhaveanoverloadedoperator.
Itisnotpossibletodefinenewoperatortokens,butyoucanusethefunction-callnotationwhentheset
ofoperatorsisnotadequate.
Syntax
Thenameofanoperatorfunctionisthekeywordoperatorfollowedbytheoperatoritself.
type operator@(argumentlist)
{
//coderealization
}
Defininganoverloadedoperatorislikedefiningafunction,butthenameofthatfunctionisoperator@,inwhich@representstheoperatorthat’sbeingoverloaded.
Thenumberofargumentsintheoverloadedoperator’sargumentlistdependsontwofactors:
unary(oneoperand)orbinary(twooperands).
globalfunction(oneargumentforunary,twoforbinary)ormemberfunction(zeroargumentsforunary,oneforbinary).
//:C12:OperatorOverloadingSyntax.cpp
#include<iostream>usingnamespacestd;
voidmain()
{
classInteger
{
inti;public:
Integer(intii):i(ii){}
inti=1,j=2,k=0;k=i+j;
Integerii(1),jj(2),kk(0);kk=ii+jj;
kk.print();//3
}///:~
voidprint(){cout<<i<<endl;}
constIntegeroperator+(constInteger&rv)const;
};
constIntegerInteger::operator+(constInteger&rv)const
{
returnInteger(i+rv.i);
}
memberfunctions
non-memberfriend
functions
Format:
Memberfunctions
typeoperator@(arguments){/*…*/}
Usage:
PrefixUnary:
@a
a.operator@()
PostfixUnary:
a@
a.operator@(int)
Binary:
a@b
a.operator@(b)
Noticetheimplicitthis.
Prefixunary:noargument;
Postfixunary:onlyoneintegralargument;
Binary:onlyoneargumentactsasitsrightoperandandthisimpliesitsleftoperand.
//complex.h; memberfunctions
classcomplex
{
public:
complex(doubler=0,doublei=0);
constcomplexoperator+(constcomplex&c);//Binaryconstcomplexoperator-();//Prefixunary
complex&operator+=(constcomplex&c);//Binary,assign
voidprint()const;private:
doublereal,imag;
};
//complex.cpp;memberfunctions
#include<iostream>#include"complex.h”usingnamespacestd;
complex::complex(doubler,doublei)
{
real=r;imag=i;
}
constcomplexcomplex::operator+(constcomplex&c)
{
doubler=real+c.real;doublei=imag+c.imag;
returncomplex(r,i);
}
//complex.cpp--continued
constcomplexcomplex::operator-()
{
returncomplex(-real,-imag);
}
complex&complex::operator+=(constcomplex&c)
{
real=real+c.real;imag=imag+c.imag;return*this;
}
voidcomplex::print()const
{
cout<<"("<<real<<","<<imag<<")"<<endl;
}
(5,9)
(10,18)
(-5,-9)
//user.cpp;memberfunctions
voidmain()
{
complexc1(3.5,5.5),c2(1.5,3.5);
complexc;
c=c1+c2;c.print();c+=c1+=c2;c.print();c=-c1;
c.print();
}
c=c1.operator+(c2);//member
c1.operator+=(c2);c.operator+=(c1);c=c1.operator-();
Friendfunctions
Format:
friendtypeoperator@(arguments){/*…*/}
Usage:
PrefixUnary:
@a
operator@(a)
PostfixUnary:
a@
operator@(a,int)
Binary:
a@b
operator@(a,b)
Notice:thereisnoimplicitthis.
//complex.h; friendfunctions
classcomplex
{
public:
complex(doubler=0,doublei=0);friendconstcomplexoperator+
(constcomplex&c1,constcomplex&c2);//Binaryfriendconstcomplexoperator-(constcomplex&c);
//Prefixunary
friendcomplex&operator+=
(complex&c1,constcomplex&c2);//Binary,assignvoidprint()const;
private:
doublereal,imag;
};
//complex.cpp; friendfunctions#include<iostream.h>
#include"complex.h"
complex::complex(doubler,doublei)
{
real=r;imag=i;
}
//notmember
constcomplexoperator+
(constcomplex&c1,constcomplex&c2)
{
doubler=c1.real+c2.real;
doublei=c1.imag+c2.imag;returncomplex(r,i);
}
//complex.cpp--continued
constcomplexoperator-(constcomplex&c)
{
returncomplex(-c.real,-c.imag);
}
complex&operator+=(complex&c1,constcomplex&c2)
{
c1.real+=c2.real;c1.imag+=c2.imag;returnc1;
}
voidcomplex::print()const
{
cout<<"("<<real<<","<<imag<<")"<<endl;
}
(5,9)
(10,18)
(-5,-9)
//user.cpp; friendfunctions
voidmain()
{
complexc1(3.5,5.5),c2(1.5,3.5);
complexc;
c=c1+c2;c.print();c+=c1+=c2;c.print();c=-c1;
c.print();
}
c=operator+(c1,c2);
operator+=(c1,c2);//notmember
operator+=(c,c1);c=operator-(c1);
Operators&ordinaryfunctions
Operatorfunctionsaredeclaredandcalledlikeordinaryfunctions.
Operatorfunctionscanbewith1or2arguments,butordinaryfunctionscanhaveseveralarguments.
Anoperatorfunctionmusteitherbeamemberortakeatleastoneargumentofauser-definedtype.
Overloadableoperators
Unaryoperators
+,-,&,!,~,++,--
Binaryoperators
=,+,-,*,/,%,+=,-=,*=,/=,
%=,&,|,^,^=,&=,|=,==,!=,>,
<,>=,<=,||,&&,<<,>>,>>=,<<=
Arguments&returnvalues
Aswithanyfunctionargument,ifyouonlyneedtoreadfromtheargumentandnotchangeit,defaulttopassingitasaconstreference.
Thetypeofreturnvalueyoushouldselectdependsontheexpectedmeaningoftheoperator.(operator+,returningaconstvalue-thesumoftwooperands)
Alltheassignmentoperatorsmodifythelvalue,returninganonconstreference.a+=b
Forthelogicaloperators,everyoneexpectstogetat
worstanintback,andatbestabool.
//memberfunctions
//Returnbyvalueasconst
constcomplexcomplex::operator+(constcomplex&c)
{
doubler=real+c.real;doublei=imag+c.imag;returncomplex(r,i);
}
complex&complex::operator+=(constcomplex&c)
(a+b)Returnbyvalueasaconst:f(a+b):theresultofa+bbecomesatemporaryconstobjectthatisusedwhencallingf().
(a+b).g():Bymakingthereturnvalueconst,itmeansonlyaconstmemberfunctioncanbecalled.
{
g
real=real+c.real;imag=imag+c.imareturn*this;
}
Constructor.Destructor.main()End.
//ThereturnoptimizationclassA
{
inti;public:
A(intx=0){i=x;cout<<"Constructor."<<endl;}
A(constA&x){i=x.i;cout<<"Copyonstructor."<<endl;}
}
Constructor.CopyConstructor.Destructor.
Destructor.main()End.
~A(){cout<<"Destructor."<<endl
Af()
Aa(1);
returna;
};
Af(){returnA(1);}voidmain()
{
f();
cout<<"main()End."<<endl;
}
Advice
Ifthefirstoperandisanobjectofanclass,theoperatorshouldbedeclaredasamemberfunction.Otherwise,itshouldbedeclaredasafriendfunction.
Example-problem
classcomplex
{
public:
complex(doubler=0,doublei=0)
{
real=r;imag=i;
}
constcomplexoperator+(constcomplex&c);voidprint()const
{ cout<<"("<<real<<","<<imag<<")"<<endl; }
private:
doublereal,imag;
};
Example-problem
constcomplexcomplex::operator+(constcomplex&c)
{
doubler=real+c.real;doublei=imag+c.imag;returncomplex(r,i);
}
voidmain()
{
complexc,c1(3.5,5.5);
c=c1+1.5; //ok:c=c1.operator+(1.5);c.print(); //(5,5.5)
c=1.5+c1; //error:c=1.5.operator+(c1);
}
Example-ok
classcomplex
{
public:
complex(doubler=0,doublei=0)
{
real=r;imag=i;
}
friendconstcomplexoperator+
(constcomplex&c1,constcomplex&c2);//Binaryvoidprint()const
{ cout<<“(”<<real<<“,”<<imag<<“)”<<endl; }private:
doublereal,imag;
};
Example-ok
constcomplexoperator+(constcomplex&c1,constcomplex&c2)
{
doubler=c1.real+c2.real;doublei=c1.imag+c2.imag;returncomplex(r,i);
}
voidmain()
{
complexc,c1(3.5,5.5);
c=c1+1.5; //ok:c=operator+(c1,1.5);c.print(); //(5,5.5)
c=1.5+c1; //ok:c=operator+(1.5,c1);
c.print(); //(5,5.5)
}
classX
{
public:
voidoperator+(int);X(int);
};
voidoperator+(X,X);
voidoperator+(X,double);voidf(Xa)
{
a+1;
//
a.operator+(1)
1+a;
//
::operator+(X(1),a)
a+1.0; //::operator+(a,1.0)
}
Specialoperators
Subscripting:[]
Dereferencing:→
IncrementandDecrement:++,--
Assignment:=
Conversion
<<,>>
Theoperator[]canbeoverloadedforaclass.
Subscripting
Note:Itmustbeoverloadedasamemberfunction.
#include<iostream>usingnamespacestd;classvect
{
public:
vect(intsize){v=newint[size];}
~vect(){delete[]v;}
int&operator[](inti); //memberfunctionprivate:
int*v;
};
int&vect::operator[](inti)
SubscriptingSubscripting12
{cout<<"Subscripting"<<endl; returnv[i];}voidmain()
{
vecta(5);
a[2]=12; //a.operator[](2)=12;cout<<a[2]<<endl;//a.operator[](2);
}
Dereferencing:->
Theoperator->mustbeoverloadedasamemberfunction.
Thefunctionshouldreturnapointertoaclass.
structStudent
{ intage;intID; };
classX
{
public:
X(){S=newStudent;S->age=0;S->ID=0;}Student*operator->(){returnS;}
~X() {deleteS;}public:
Student*S;
};
voidmain()
{
Xx;
x->age=20;//(x.operator->())->age=20;x->ID=001;//(x.operator->())->ID=001;
}
IncrementandDecrement
Theincrement(++)anddecrement(--)operatorscanbeusedasbothprefixandpostfixoperators.Forexample:
intx=10; x++; ++x;intx=10; x--; --x;
Soifweoverloadthesetwooperators,weshouldgivefouroperatorfunctions.
Generallytheyareoverloadedasmemberfunctions.
IncrementandDecrement
Syntaxofincrementoverloadingisasfollows:Prefix: typeoperator++()
Postfix: typeoperator++(int)
Prefix: typeoperator--()Postfix: typeoperator--(int)
Theintargumentisusedtoindicatethatthefunctionistobeinvokedforpostfixapplicationof
++or--.Thisintisneverused;theargumentis
simplyadummyusedtodistinguishbetweenprefixandpostfixapplication.
#include<iostream>usingnamespacestd;classIncrease
{
public:
Increase(intval=0){value=val;}
voiddisplay()const{cout<<value<<endl;}Increaseoperator++(); //prefixIncreaseoperator++(int); //postfix
private:
intvalue;
};
IncreaseIncrease::operator++() //prefix
{
cout<<"++value"<<endl;
++value;return*this;
}
IncreaseIncrease::operator++(int)//postfix
{
cout<<"value++"<<endl;inttemp=value;value++;returnIncrease(temp);
}
++value11
value++
10
voidmain()
{
Increasea(10),b(10),c;c=++a; //a.operator++();c.display();
c=b++; //b.operator++(int);c.display();
}
(4)Assignment:=
(5)Conversion
(6) <<,>>
Operatorsyoucan’toverload
. memberselection
.*memberselectionbyapointer
:: scoperesolution
?:ternaryconditionalexpression
sizeof
Typeid
There’snoexponentiationoperator.
Therearenonewuser-definedoperators.
Youcan’tchangetheprecedencerules.
membersornon-member?
Whichshouldyouchoose,membersornon-member?
Overloadingassignment
Syntaxofassignmentoverloadingisasfollows:
X&X::operator=(constX&from)
{
//copydatafromtheargument
}
Datet1; //constructor
Datet2=t1;//copyconstructor
Datet3; //constructor
t3=t2; //assignmentoperator
Theaim:acreatedclassobjectcanbeupdatedwithacopyofanothercreatedobjectofthesameclass.
Ifauserhasdeclaredaassignmentoperator,itwillbeused;ifnot,thecompilerwilltryto
generatepublicone.
classLocation
{
public:
Location(intxx=0,intyy=0){X=xx;Y=yy;}//defaultconstructorLocation(constLocation&p) //copyconstructor
{ X=p.X;Y=p.Y;
cout<<“Copyconstructorcalled.”<<endl;
}
Location&operator=(constLocation&p); //assignmentintGetX(){returnX;}
intGetY(){returnY;}private:
intX,Y;
};
Location&Location::operator=(constLocation&p)
{ X=p.X;Y=p.Y;
cout<<"Assignmentoperatorcalled."<<endl;return*this;
}
voidmain()
{
LocationA(1,2),B;B=A;cout<<"B="<<B.GetX()<<","<<B.GetY()<<endl;
Assignmentoperatorcalled.B=1,2
};
{voidmain()LocationA(1,2);LocationB=A;
cout<<"B="<<B.GetX()<<","<<B.GetY()<<endl;
};
Whenoverloadingaoperator,wecannotchange:
numberofoperands
priority
structureofsyntax
combination
Forbuild-intypes,a=a+1isequivalenttoa+=1,whichisnotforuser-definedtypesunlessyouhappentodefinethemthatway.AcompilerwillnotgenerateX::operator+=()fromthedefinitionsofX::operator+()andX::operator=().
User-definedCopyConstructorandAssignmentOperator
Acopyconstructorandaassignmentoperatormustbedefinedwhenusedonobjectsofaclasswithpointermembers.
Otherwise,itmaycauseasurprising(andusuallyundesired)effect.
classA
{
int*p;public:
A(inti){p=newint(i);}
~A(){deletep;}
};
voidmain()
{
a.pandb.ppointtothesamestorage.
Thestorage(5)willbereleasedtwice.
Aa(5);
Ab(a); //copyconstructorAc(6),d(10);
d=c; //assignmentoperator
c.pandd.ppointtothesamestorage.Thestorage(6)willbereleasedtwice.Thestorage(10)islostforever.
};
a.p
5
b.p
c.p d.p
d.p
6
10
classA{
int*p;public:
A(inti){p=newint(i);}
~A(){deletep;}
A(constA&r); //copyconsructor
modification
A&operator=(constA&r); //assignment
};
A::A(constA&r){p=newint(*r.p);}//copyconsructorA&A::operator=(constA&r) //assignment
{
if(this==&r)return*this;//self-assignment:r=rdeletep;
p=newint(*r.p);
return*this;
}
voidmain()
{
Aa(5);
Ab(a); //copyconstructorAc(6),d(10);
d=c; //assignmentoperator
}
5
5
a.p
b.p
c.p
6
10
6
d.p
classA
{
example
int*p;public:
A(inti){cout<<"Constructor"<<endl;p=newint(i);}
~A(){cout<<"Destructor"<<endl;deletep;}A(constA&r)//copyconsructor
{cout<<"Copy-constructor"<<endl;p=newint(*r.p);}
A&operator=(constA&r);//assignment
voidoutput(){cout<<p<<"->"<<*p<<endl;}
};
A&A::operator=(constA&r) //assignment
{
cout<<"Assignment"<<endl;
if(this==&r)return*this;//self-assignment:r=r
deletep;
p=newint(*r.p);return*this;
}
intmain()
{
Aa(5);
Ab(a);//copyconsructorAc(6),d(10);
d=c; //assignmenta.output();
b.output();
c.output();
d.output();return0;
}
Automatictypeconversion
Aconstructorcanbeusedtospecifytypeconversion.
Thesecondwaytoproduceautomatictypeconversionisthroughoperatoroverloading.
Constructorconversion
#include<iostream>classcomplex
{
public:
complex(doubler=0,doublei=0);complex(constcomplex&a);friendconstcomplexoperator+
(constcomplex&c1,constcomplex&c2);private:
doublereal,imag;
};
complex::complex(doubler,doublei)
{
real=r;imag=i;
cout<<"constructor:"<<real<<","<<imag<<endl;
}
complex::complex(constcomplex&a)
{
real=a.real;imag=a.imag;
cout<<"copyconstructor:"<<real<<","<<imag<<endl;
}
constcomplexoperator+
(constcomplex&c1,constcomplex&c2)
{
doubler=c1.real+c2.real;doublei=c1.imag+c2.imag;returncomplex(r,i);//
}
voidmain()
{
complexc,c1(3.5,5.5);
c=c1+1.5; //ok:c=operator+(c1,complex(1.5));
}
c c1
double-->complex
returnc
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年維修申請(qǐng)報(bào)告(28篇)
- 跨境電商平臺(tái)的智能技術(shù)應(yīng)用
- 預(yù)防瘧疾知識(shí)培訓(xùn)課件
- 廣東茂名農(nóng)林科技職業(yè)學(xué)院《中學(xué)生物學(xué)課程標(biāo)準(zhǔn)與教材分析》2023-2024學(xué)年第二學(xué)期期末試卷
- 河北省張家口市萬(wàn)全縣2025年數(shù)學(xué)三下期末檢測(cè)模擬試題含解析
- 吉林醫(yī)藥學(xué)院《社會(huì)保險(xiǎn)學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 天津財(cái)經(jīng)大學(xué)《跨境電子商務(wù)模擬》2023-2024學(xué)年第二學(xué)期期末試卷
- 燃料油硫化物濃度管理措施
- 2025屆玉樹藏族自治州雜多縣數(shù)學(xué)三下期末經(jīng)典試題含解析
- 沈陽(yáng)北軟信息職業(yè)技術(shù)學(xué)院《數(shù)字成像技術(shù)》2023-2024學(xué)年第二學(xué)期期末試卷
- 根管治療病例分享
- 數(shù)學(xué)課后訓(xùn)練:正態(tài)分布
- DB5115-T 129-2024《油樟優(yōu)樹選擇技術(shù)規(guī)程》
- (完整版)西泠印社出版社三年級(jí)下冊(cè)《書法練習(xí)指導(dǎo)》完整教案
- 《電工儀表與測(cè)量》課程教學(xué)大綱
- 【企業(yè)盈利能力探析的國(guó)內(nèi)外文獻(xiàn)綜述2400字】
- 危急值的考試題及答案
- 食品安全制度目錄
- 新犯罪學(xué)完整版課件電子教案
- 2025新高考方案一輪物理參考答案與詳解
- 數(shù)字孿生與光伏儲(chǔ)能集成
評(píng)論
0/150
提交評(píng)論