《“+”运算符.ppt》由会员分享,可在线阅读,更多相关《“+”运算符.ppt(84页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、程序设计 cs.sjtu 2011.9程序设计-1第第11章章运算符重载运算符重载v什么是运算符重什么是运算符重载v运算符重运算符重载的方法的方法v几个特殊的运算符的重几个特殊的运算符的重载v自定自定义类型型转换运算符运算符v运算符重运算符重载实例例程序设计 cs.sjtu 2011.9程序设计-2什么是运算符重载什么是运算符重载v使系使系统内置的运算符可以用于内置的运算符可以用于类类型型v例如:例如:+运算符能运算符能够实现2 2个个对象象间的加。的加。例如:例如:类A A的的对象象a1a1、a2a2、a3a3,希望:,希望:a3=a1+a2a3=a1+a2;即即:分分别把把对象象a1a1和
2、和a2a2的的各各个个数数据据成成员值对应相加,然后相加,然后赋给对象象a3a3。程序设计 cs.sjtu 2011.9程序设计-3问题的提出问题的提出v把把某某些些事事交交给系系统去去做做,用用户只只要要知知道道相加就可相加就可v扩充运算符的功能充运算符的功能v增增强了了C+C+语言的可言的可扩充性充性v使用使用户定定义的的类更像系更像系统的内置的内置类型型程序设计 cs.sjtu 2011.9程序设计-4运算符重载的限制运算符重载的限制v不是所有的运算符都能重不是所有的运算符都能重载v重重载不能改不能改变运算符的运算符的优先先级和和结合性合性v重重载不能改不能改变运算符的操作数个数运算符的
3、操作数个数v不能不能创建新的运算符建新的运算符程序设计 cs.sjtu 2011.9程序设计-5可以重载的运算符可以重载的运算符+-*/%&|!=+=-=*=/=%=&=|=!=&|+-*,-()newdeletenewdelete程序设计 cs.sjtu 2011.9程序设计-6不能重载的运算符不能重载的运算符.*:?:sizeof程序设计 cs.sjtu 2011.9程序设计-7第第11章章运算符重载运算符重载v什么是运算符重什么是运算符重载v运算符重运算符重载的方法的方法v几个特殊的运算符的重几个特殊的运算符的重载v自定自定义类型型转换运算符运算符v运算符重运算符重载实例例程序设计 cs
4、.sjtu 2011.9程序设计-8运算符重载的方法运算符重载的方法v运算符重运算符重载就是写一个函数解就是写一个函数解释某个运算符在某个运算符在某个某个类中的含中的含义v要使得系要使得系统能自能自动找到重找到重载的的这个函数,函数个函数,函数名必名必须要体要体现出和某个被重出和某个被重载的运算符的的运算符的联系。系。vC+中中规定,重定,重载函数名函数名为operator其中,其中,为要重要重载的运算符。如要重的运算符。如要重载“+”运算符,运算符,该重重载函数名函数名为operator+。要重。要重载赋值运算符,函数名运算符,函数名为operator=。程序设计 cs.sjtu 2011.
5、9程序设计-9函数原型v运算符的重运算符的重载不能改不能改变运算符的运算运算符的运算对象数。因此,重象数。因此,重载函数的形式参数个数(包括成函数的形式参数个数(包括成员函数的函数的隐式指式指针this)与运)与运算符的运算算符的运算对象数相同象数相同v运算符重运算符重载可以重可以重载成成成成员函数也可以重函数也可以重载成全局函数成全局函数实现。重。重载成全局函数成全局函数时,最好把此函数,最好把此函数设为友友员函数函数v如果作如果作为类的成的成员函数,它的形式参数个数比运算符的运函数,它的形式参数个数比运算符的运算算对象数少象数少1。这是因是因为成成员函数有一个函数有一个隐含的参数含的参数t
6、his。在在C+中,把中,把隐含参数含参数this作作为运算符的第一个参数。运算符的第一个参数。v当把一个一元运算符重当把一个一元运算符重载成成成成员函数函数时,该函数没有形式函数没有形式参数。参数。v把一个二元运算符重把一个二元运算符重载成成成成员函数函数时,该函数只有一个形函数只有一个形式参数,就是右操作数,当前式参数,就是右操作数,当前对象是左操作数。象是左操作数。程序设计 cs.sjtu 2011.9程序设计-10重载实例重载实例v为rational类增加增加“+”和和“*”以及比以及比较的重的重载函数,用以替函数,用以替换现有的有的add和和multi函数函数程序设计 cs.sjtu
7、 2011.9程序设计-11方案一:重载成成员函数方案一:重载成成员函数classRationalprivate:intnum;intden;voidReductFraction();public:Rational(intn=0,intd=1)num=n;den=d;Rationaloperator+(constRational&r1)const;Rationaloperator*(constRational&r1)const;booloperator(constRational&r1)const;booloperator=(constRational&r1)const;booloperato
8、r!=(constRational&r1)const;voiddisplay()coutnum/den;程序设计 cs.sjtu 2011.9程序设计-12函数实现函数实现RationalRational:operator+(constRational&r1)constRationaltmp;tmp.num=num*r1.den+r1.num*den;tmp.den=den*r1.den;tmp.ReductFraction();returntmp;RationalRational:operator*(constRational&r1)constRationaltmp;tmp.num=num*
9、r1.num;tmp.den=den*r1.den;tmp.ReductFraction();returntmp;程序设计 cs.sjtu 2011.9程序设计-13boolRational:operator(constRational&r1)constreturnnum*r1.den(constRational&r1)constreturnnum*r1.denden*r1.num;boolRational:operator=(constRational&r1)constreturnnum*r1.den=(constRational&r1)constreturnnum*r1.den=den*r
10、1.num;boolRational:operator!=(constRational&r1)constreturn!(*this=r1);程序设计 cs.sjtu 2011.9程序设计-14方案二:重载成友员函数方案二:重载成友员函数classRationalfriendRationaloperator+(constRational&r1,constRational&r2);friendRationaloperator*(constRational&r1,constRational&r2);friendbooloperator(constRational&r1,constRational&r
11、2);friendbooloperator=(constRational&r1,constRational&r2);friendbooloperator!=(constRational&r1,constRational&r2);private:intnum;intden;voidReductFraction();public:Rational(intn=0,intd=1)num=n;den=d;voiddisplay()coutnum/den;程序设计 cs.sjtu 2011.9程序设计-15函数的实现函数的实现Rationaloperator+(constRational&r1,const
12、Rational&r2)Rationaltmp;tmp.num=r1.num*r2.den+r2.num*r1.den;tmp.den=r1.den*r2.den;tmp.ReductFraction();returntmp;Rationaloperator*(constRational&r1,constRational&r2)Rationaltmp;tmp.num=r1.num*r2.num;tmp.den=r1.den*r2.den;tmp.ReductFraction();returntmp;其他函数其他函数实现略略程序设计 cs.sjtu 2011.9程序设计-16重载后有理数类的使用
13、重载后有理数类的使用intmain()Rationalr1(1,6),r2(1,6),r3;r3=r1+r2;r1.display();cout+;r2.display();cout=;r3.display();coutendl;r3=r1*r2;r1.display();cout*;r2.display();cout=;r3.display();cout)必)必须重重载成成成成员函数。函数。v具有具有赋值意意义的运算符,如复合的的运算符,如复合的赋值运算符以及运算符以及+和和-,不一定非要定,不一定非要定义为成成员函数,但最好定函数,但最好定义为成成员函数。函数。v具有两个运算具有两个运算对
14、象的运算符最好重象的运算符最好重载为全局函数,全局函数,这样可可以使得以使得应用更加灵活。如果把加运算定用更加灵活。如果把加运算定义成全局函数,成全局函数,r是有理数是有理数类的的对象,象,则2+r是一个合法的表达式。是一个合法的表达式。程序设计 cs.sjtu 2011.9程序设计-18第第11章章运算符重载运算符重载v什么是运算符重什么是运算符重载v运算符重运算符重载的方法的方法v几个特殊的运算符的重几个特殊的运算符的重载v自定自定义类型型转换运算符运算符v运算符重运算符重载实例例程序设计 cs.sjtu 2011.9程序设计-19几个特殊的运算符的重载几个特殊的运算符的重载v赋值运算符运
15、算符v下下标运算符运算符v函数函数调用运算符用运算符v+和和运算符的重运算符的重载v重重载函数的原型函数的原型设计考考虑v输入入输出运算符重出运算符重载程序设计 cs.sjtu 2011.9程序设计-20赋值运算符赋值运算符v对任一任一类,如果用,如果用户没有自定没有自定义赋值运算运算符函数,那么系符函数,那么系统为其生成一个缺省的其生成一个缺省的赋值运算符函数,在运算符函数,在对应的数据成的数据成员间赋值。v一般情况下,一般情况下,这个缺省的个缺省的赋值运算符重运算符重载函数能函数能满足用足用户的需求。但是,当的需求。但是,当类含有含有类型型为指指针的数据成的数据成员时,可能会,可能会带来一
16、来一些麻些麻烦。程序设计 cs.sjtu 2011.9程序设计-21对对DoubleArray类对象执行类对象执行array1=array2的问题的问题v会引起内存泄漏会引起内存泄漏v使使这两个数两个数组的元素存放于同一的元素存放于同一块空空间中中v当当这两个两个对象析构象析构时,先析构的,先析构的对象会象会释放存放存储数数组元素的空元素的空间。而当后一个。而当后一个对象象析构析构时,无法,无法释放存放数放存放数组元素的空元素的空间程序设计 cs.sjtu 2011.9程序设计-22赋值运算符“=”的原型v赋值运算符只能重运算符只能重载成成成成员函数函数v函数原型:函数原型:X&X:opera
17、tor=(constX&source)/赋值过程程一旦一旦创建了建了对象象x1,x2,可以用可以用x1=x2赋值。程序设计 cs.sjtu 2011.9程序设计-23DoubleArray类的类的赋值运算符重载函数赋值运算符重载函数DoubleArray&DoubleArray:operator=(constDoubleArray&right)if(this=&right)return*this;deletestorage;low=right.low;high=right.high;storage=newdoublehigh-low+1;for(inti=0;i=high-low;+i)sto
18、ragei=right.storagei;/复制数复制数组元素元素return*this;程序设计 cs.sjtu 2011.9程序设计-24赋值运算符重载要点赋值运算符重载要点v一般来一般来讲,需要自定,需要自定义拷拷贝构造函数的构造函数的类也需要也需要自定自定义赋值运算符重运算符重载函数。函数。v在在赋值运算符重运算符重载函数中,已函数中,已经将参数的将参数的值赋值给了当前了当前对象,那象,那为什么什么还需要返回需要返回值呢?呢?记住,住,在在C+中,中,赋值是一个运算,它可以形成一个表是一个运算,它可以形成一个表达式,而达式,而该表达式的表达式的结果果值就是就是赋给左左边的的对象象的的值
19、。因此,。因此,赋值运算符重运算符重载函数必函数必须返回返回赋给左左边的的对象象值。程序设计 cs.sjtu 2011.9程序设计-25赋值运算符重载和拷贝构造函数赋值运算符重载和拷贝构造函数v一般来一般来讲,需要拷,需要拷贝构造函数的构造函数的类也需也需要重要重载赋值运算符运算符v定定义对象象时给对象象赋初初值调用的是拷用的是拷贝构造函数构造函数v程序的程序的语句部分中的句部分中的赋值语句句调用的是用的是赋值运算符重运算符重载函数函数程序设计 cs.sjtu 2011.9程序设计-26几个特殊的运算符的重载几个特殊的运算符的重载v赋值运算符运算符v下下标运算符运算符v函数函数调用运算符用运算
20、符v+和和运算符的重运算符的重载v重重载函数的原型函数的原型设计考考虑v输入入输出运算符重出运算符重载程序设计 cs.sjtu 2011.9程序设计-27下标运算符重载下标运算符重载v能否象普通的数能否象普通的数组那那样通通过下下标运算操作运算操作DoubleArray类的的对象,象,这样可以使可以使DoubleArray类更像一个功能内置的数更像一个功能内置的数组。v可以通可以通过重重载下下标运算符(运算符()来)来实现v下下标运算符是二元运算符,第一个运算数是数运算符是二元运算符,第一个运算数是数组名,第二个运算数是下名,第二个运算数是下标值v下下标运算符必运算符必须重重载成成成成员函数函
21、数程序设计 cs.sjtu 2011.9程序设计-28DoubleArray类的类的重载重载double&DoubleArray:operator(intindex)if(indexhigh)cout下下标越界越界;exit(-1);returnstorageindex-low;程序设计 cs.sjtu 2011.9程序设计-29DoubleArray类的使用类的使用v定定义:DoubleArrayarray(20,30);v数数组输入:入:for(i=20;i=30;+i)cout请输入第入第iarrayi;v数数组输出:出:for(i=20;i=30;+i)coutarrayiend|st
22、arthigh)cout下下标越界越界;exit(-1);DoubleArraytmp(lh,lh+end-start);for(inti=0;iend-start+1;+i)tmp.storagei=storagestart+i-low;returntmp;程序设计 cs.sjtu 2011.9程序设计-35几个特殊的运算符的重载几个特殊的运算符的重载v赋值运算符运算符v下下标运算符运算符v函数函数调用运算符用运算符v+和和运算符的重运算符的重载v重重载函数的原型函数的原型设计考考虑v输入入输出运算符重出运算符重载程序设计 cs.sjtu 2011.9程序设计-36“+”和“-”重载v、-:
23、是一元操作符:是一元操作符v这两个操作符可以是前两个操作符可以是前缀,也可以是后,也可以是后缀。而且前。而且前缀和后和后缀的含的含义是有区是有区别的。的。所以,必所以,必须有两个重有两个重载函数。函数。v问题:两个重:两个重载函数有相同的原型函数有相同的原型v区分方法:区分方法:前前缀:一元操作符。:一元操作符。后后缀:二元操作符。:二元操作符。程序设计 cs.sjtu 2011.9程序设计-37“+”和和“-”重载重载cont.v成成员函数重函数重载+ob重重载为:ob.operator+()ob-重重载为:ob.operator-(int)v友元函数重友元函数重载+ob重重载为:opera
24、tor+(X&ob)ob-重重载为:operator-(X&ob,int)v调用用时,参数,参数int一般一般传递给值0。程序设计 cs.sjtu 2011.9程序设计-38+、-重载实例重载实例v设计一个会一个会报警的警的计数器数器类。该计数器数器从从0开始开始计数,当到达数,当到达预先先设定好的定好的报警警值时,计数器会数器会发出出报警消息,警消息,计数器数器的的值不再增加。不再增加。程序设计 cs.sjtu 2011.9程序设计-39类定义类定义classCounterintvalue;/计数器的数器的值intalarm;/报警警值public:Counter(inta)value=0;
25、alarm=a;Counter&operator+();/前前缀的的+重重载Counteroperator+(int);/后后缀的的+重重载voidprint()coutvalueendl;程序设计 cs.sjtu 2011.9程序设计-40类实现类实现Counter&Counter:operator+()if(value=alarm)cout已超已超过报警警值n;else+value;if(value=alarm)cout已到达已到达报警警值n;return*this;CounterCounter:operator+(intx)Countertmp=*this;/保存保存对象修改前的状象修改
26、前的状态if(value=alarm)cout已超已超过报警警值n;else+value;if(value=alarm)cout)()和流提取运算符和流提取运算符()()输入和输出用户自定输入和输出用户自定义类的对象义类的对象程序设计 cs.sjtu 2011.9程序设计-48输出重载函数的原型输出重载函数的原型ostream&operator(ostream&os,constClassType&obj)os要要输出的内容;出的内容;returnos;程序设计 cs.sjtu 2011.9程序设计-49实例实例ostream&operator(ostream&os,constRational&
27、obj)/输出重出重载函数函数osobj.num/obj.den;returnos;如定如定义:Rationalr(2,6);执行行cout)()和流提取运算符和流提取运算符()(istream&is,ClassType&obj)is要要输入的内容;入的内容;returnis;程序设计 cs.sjtu 2011.9程序设计-52实例实例istream&operator(istream&in,Rational&obj)/输入重入重载函数函数inobj.numobj.den;obj.ReductFraction();returnin;如定如定义:Rationalr;可以用可以用cinr从从键盘输入
28、入r的数据。如的数据。如输入入为:13执行行cout(istream&in,Rational&obj);friendostream&operator(ostream&os,constRational&obj);friendRationaloperator+(constRational&r1,constRational&r2);friendRationaloperator*(constRational&r1,constRational&r2);private:intnum;intden;voidReductFraction();public:Rational(intn=0,intd=1)num=
29、n;den=d;operatordouble()constreturn(double(num)/den);程序设计 cs.sjtu 2011.9程序设计-63Rational类的使用类的使用#include#includeRational.hintmain()Rationalr1,r2,r3,r4;doublex;coutr1;coutr2;r3=r1+r2;coutr1+r2=r3endl;r3=r1*r2;coutr1*r2=r3endl;r4=(r1+r2)*r3;cout(r1+r2)*r3的的值为:r4endl;x=5.5-r1;cout5.5-r1的的值为:xendl;cout(r
30、1r2?r1:r2)endl;return0;输入输入r1:13输入输入r2:261/3+1/3=2/31/3*1/3=1/9(r1+r2)*r3的值为的值为2/275.5-r1的值为:的值为:5.166671/3 程序设计 cs.sjtu 2011.9程序设计-64第第11章章运算符重载运算符重载v什么是运算符重什么是运算符重载v运算符重运算符重载的方法的方法v几个特殊的运算符的重几个特殊的运算符的重载v自定自定义类型型转换运算符运算符v运算符重运算符重载实例例程序设计 cs.sjtu 2011.9程序设计-65运算符重载实例运算符重载实例v完善完善DoubleArray类程序设计 cs.s
31、jtu 2011.9程序设计-66DoubleArray.h#ifndef_array_h#define_array_h#includeclassDoubleArrayfriendostream&operator(istream&is,DoubleArray&obj);friendbooloperator=(constDoubleArray&obj1,constDoubleArray&obj2);private:intlow;inthigh;double*storage;程序设计 cs.sjtu 2011.9程序设计-67public:DoubleArray(intlh=0,intrh=0):
32、low(lh),high(rh)storage=newdoublehigh-low+1;DoubleArray(constDoubleArray&arr);DoubleArray&operator=(constDoubleArray&right);double&operator(intindex);constdouble&operator(intindex)const;DoubleArrayoperator()(intstart,intend,intlh);DoubleArray()deletestorage;#endif程序设计 cs.sjtu 2011.9程序设计-68DoubleArra
33、y.cpp/文件名文件名:DoubleArray.cpp/DoubleArray类的的实现#include#includeDoubleArray.h“DoubleArray:DoubleArray(constDoubleArray&arr)low=arr.low;high=arr.high;storage=newdoublehigh-low+1;for(inti=0;ihigh-low+1;+i)storagei=arr.storagei;程序设计 cs.sjtu 2011.9程序设计-69operator=DoubleArray&DoubleArray:operator=(constDoub
34、leArray&a)if(this=&a)return*this;deletestorage;low=a.low;high=a.high;storage=newdoublehigh-low+1;for(inti=0;i=low&index=low&index=high);returnstorageindex-low;程序设计 cs.sjtu 2011.9程序设计-71operatorostream&operator(ostream&os,constDoubleArray&obj)os数数组内容内容为:n;for(inti=obj.low;i=obj.high;+i)osobjit;osistr
35、eam&operator(istream&is,DoubleArray&obj)cout请输入数入数组元素元素obj.low,obj.high:n;for(inti=obj.low;iobji;returnis;程序设计 cs.sjtu 2011.9程序设计-73operator=booloperator=(constDoubleArray&obj1,constDoubleArray&obj2)if(obj1.low!=obj2.low|obj1.high!=obj2.high)returnfalse;for(inti=obj1.low;i=obj1.high;+i)if(obj1i!=obj
36、2i)returnfalse;returntrue;程序设计 cs.sjtu 2011.9程序设计-74operator()DoubleArrayDoubleArray:operator()(intstart,intend,intlh)assert(start=low&end=high);DoubleArraytmp(lh,lh+end-start);for(inti=0;iarray1;coutarray1;coutarray1;array2=array1;cout执行行array2=array1,array2array2;coutarray1=array2是是(array1=array2)
37、?true:false)endl;array225=0;cout执行行array25=0后后,array1=array2是是(array1=array2)?true:false)endl;array2=array1(22,25,2);cout执行行array2=array1(22,25,2)后后,array2的的值为:(istream&is,Complex&obj);friendostream&operator(istream&is,Complex&obj)coutobj.real;/利用利用Rational类的的输入重入重载实现实部的部的输入入coutobj.imag;/利用利用Rational类的的输入重入重载实现虚部的虚部的输入入returnis;ostream&operator(ostream&os,constComplex&obj)/利用利用Rational类的的输出重出重载实现实部和虚部的部和虚部的输出出cout(obj.real+obj.imagi);returnos;程序设计 cs.sjtu 2011.9程序设计-84复数类的使用复数类的使用intmain()Complexx1,x2,x3;coutx1;coutx2;x3=x1+x2;coutx1+x2=x3endl;return0;