2022年面向?qū)ο蠹夹g(shù)與方法0216人_第1頁(yè)
2022年面向?qū)ο蠹夹g(shù)與方法0216人_第2頁(yè)
2022年面向?qū)ο蠹夹g(shù)與方法0216人_第3頁(yè)
2022年面向?qū)ο蠹夹g(shù)與方法0216人_第4頁(yè)
2022年面向?qū)ο蠹夹g(shù)與方法0216人_第5頁(yè)
已閱讀5頁(yè),還剩92頁(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)介

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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論