第八讲 运算符重载(8.2)

上传人:夏** 文档编号:569510232 上传时间:2024-07-30 格式:PPT 页数:34 大小:563KB
返回 下载 相关 举报
第八讲 运算符重载(8.2)_第1页
第1页 / 共34页
第八讲 运算符重载(8.2)_第2页
第2页 / 共34页
第八讲 运算符重载(8.2)_第3页
第3页 / 共34页
第八讲 运算符重载(8.2)_第4页
第4页 / 共34页
第八讲 运算符重载(8.2)_第5页
第5页 / 共34页
点击查看更多>>
资源描述

《第八讲 运算符重载(8.2)》由会员分享,可在线阅读,更多相关《第八讲 运算符重载(8.2)(34页珍藏版)》请在金锄头文库上搜索。

1、 运算符重载概述运算符重载概述 重载重载单目单目运算符运算符 重载重载双目双目运算符运算符 重载重载赋值赋值运算符运算符运算符重载运算符重载运算符重载运算符重载是对已有运算符赋予多重含义,同是对已有运算符赋予多重含义,同是对已有运算符赋予多重含义,同是对已有运算符赋予多重含义,同一个运算符用于不同类型的数据将导致不同类型的一个运算符用于不同类型的数据将导致不同类型的一个运算符用于不同类型的数据将导致不同类型的一个运算符用于不同类型的数据将导致不同类型的行为。行为。行为。行为。注意:注意:注意:注意:运算符重载实质上就是运算符重载实质上就是运算符重载实质上就是运算符重载实质上就是函数重载函数重载

2、函数重载函数重载。在实。在实。在实。在实现过程中,现过程中,现过程中,现过程中,首先首先首先首先把指定的运算符表达式转化成把指定的运算符表达式转化成把指定的运算符表达式转化成把指定的运算符表达式转化成对运算符函数的调用,运算对象转化成运算符对运算符函数的调用,运算对象转化成运算符对运算符函数的调用,运算对象转化成运算符对运算符函数的调用,运算对象转化成运算符函数的实参,函数的实参,函数的实参,函数的实参,然后然后然后然后根据实参的类型来确定需要根据实参的类型来确定需要根据实参的类型来确定需要根据实参的类型来确定需要调用的函数,这个过程是在调用的函数,这个过程是在调用的函数,这个过程是在调用的函

3、数,这个过程是在编译过程编译过程编译过程编译过程中完成的中完成的中完成的中完成的。+ +- -* */ /% & &| | ! != = +=+=-=-=*=*=/=/=%=%=&=&=|=|=!=!=&| |+- -*, ,- () ()NewNewdeletedelete. .* .*: :?:?:sizeofsizeof C+C+中的运算符除了少数几个之外,全部可以重载,中的运算符除了少数几个之外,全部可以重载,中的运算符除了少数几个之外,全部可以重载,中的运算符除了少数几个之外,全部可以重载,而且而且而且而且只能重载已有的这些运算符只能重载已有的这些运算符只能重载已有的这些运算符只能重

4、载已有的这些运算符 重载之后,重载之后,重载之后,重载之后,运算符的优先级和结合性运算符的优先级和结合性运算符的优先级和结合性运算符的优先级和结合性都不会改变都不会改变都不会改变都不会改变 运算符重载是针对新类型数据的实际需要,对原有运算符重载是针对新类型数据的实际需要,对原有运算符重载是针对新类型数据的实际需要,对原有运算符重载是针对新类型数据的实际需要,对原有运算符进行的适当改造。一般来讲,运算符进行的适当改造。一般来讲,运算符进行的适当改造。一般来讲,运算符进行的适当改造。一般来讲,重载的功能应当重载的功能应当重载的功能应当重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个与原

5、有功能相类似,不能改变原运算符的操作对象个与原有功能相类似,不能改变原运算符的操作对象个与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型数,同时至少要有一个操作对象是自定义类型数,同时至少要有一个操作对象是自定义类型数,同时至少要有一个操作对象是自定义类型。注意:注意:注意:注意:与使用明确的函数调用相比,如果完成相同的操作与使用明确的函数调用相比,如果完成相同的操作与使用明确的函数调用相比,如果完成相同的操作与使用明确的函数调用相比,如果完成相同的操作运算符重载可以使程序更清晰,则使用运算符重载。但要运算符重载可以使程序更清晰,则使用运算符重载。但要运算

6、符重载可以使程序更清晰,则使用运算符重载。但要运算符重载可以使程序更清晰,则使用运算符重载。但要避免运算符重载过度使用或者使用不一致,这将导致称故避免运算符重载过度使用或者使用不一致,这将导致称故避免运算符重载过度使用或者使用不一致,这将导致称故避免运算符重载过度使用或者使用不一致,这将导致称故函数模糊和可读性差。函数模糊和可读性差。函数模糊和可读性差。函数模糊和可读性差。运算符重载形式有两种:运算符重载形式有两种:运算符重载形式有两种:运算符重载形式有两种: 重载为类的成员函数重载为类的成员函数重载为类的成员函数重载为类的成员函数 重载为类的友元函数重载为类的友元函数重载为类的友元函数重载为

7、类的友元函数格式格式格式格式1 1:使运算符函数重:使运算符函数重:使运算符函数重:使运算符函数重载为类的成员函数载为类的成员函数载为类的成员函数载为类的成员函数函数类型函数类型函数类型函数类型 operator operator 运运运运算符算符算符算符( (形参表形参表形参表形参表) ) 函数体函数体函数体函数体;格式格式格式格式2 2:使运算符函数:使运算符函数:使运算符函数:使运算符函数重载为类的友元函数重载为类的友元函数重载为类的友元函数重载为类的友元函数friendfriend operator operator 运运运运算符算符算符算符( (形参表形参表形参表形参表) ) 函数体

8、函数体函数体函数体;注意:注意:注意:注意:当运算符重载为当运算符重载为当运算符重载为当运算符重载为类的成类的成类的成类的成员函数员函数员函数员函数时,函数的参数个数比时,函数的参数个数比时,函数的参数个数比时,函数的参数个数比原来的运算符个数要原来的运算符个数要原来的运算符个数要原来的运算符个数要少一个少一个少一个少一个(后缀(后缀(后缀(后缀+/-+/-除外除外除外除外););););当重载当重载当重载当重载为类的为类的为类的为类的友元函数友元函数友元函数友元函数时,参数个数时,参数个数时,参数个数时,参数个数与原运算符的与原运算符的与原运算符的与原运算符的个数相同个数相同个数相同个数相同

9、一般而言,单目运算符最好重载为成员函数,而双目一般而言,单目运算符最好重载为成员函数,而双目一般而言,单目运算符最好重载为成员函数,而双目一般而言,单目运算符最好重载为成员函数,而双目运算符最好重载为友元函数运算符最好重载为友元函数运算符最好重载为友元函数运算符最好重载为友元函数C+C+中单目运算符只有中单目运算符只有中单目运算符只有中单目运算符只有“ “+”+”和和和和“ “-”-”例例例例1 1 分析以下程序的执行结果分析以下程序的执行结果分析以下程序的执行结果分析以下程序的执行结果#include using namespace std;class Sampleint n;public:

10、Sample(int i)n=i; void operator +() n+; /”+”运算符重运算符重载载void display()coutn=nendl;int main() Sample A(5);A+;A.display(); return 0; A+;+A;“ “+”+”和和和和“ “-”-”重载运算符也有重载运算符也有重载运算符也有重载运算符也有前缀和后缀前缀和后缀前缀和后缀前缀和后缀两种运两种运两种运两种运算符重载形式。其语法格式如下:算符重载形式。其语法格式如下:算符重载形式。其语法格式如下:算符重载形式。其语法格式如下:函数类型函数类型函数类型函数类型 operator o

11、perator +();+(); / /前缀运算前缀运算前缀运算前缀运算函数类型函数类型函数类型函数类型 operator operator +(+(intint);); / /后缀运算后缀运算后缀运算后缀运算使用使用使用使用前缀前缀前缀前缀运算符的语法格式如下:运算符的语法格式如下:运算符的语法格式如下:运算符的语法格式如下:+对象对象对象对象; ;使用使用使用使用后缀后缀后缀后缀运算符的语法格式如下:运算符的语法格式如下:运算符的语法格式如下:运算符的语法格式如下:对象对象对象对象+;+;注意注意注意注意:当重载单目运算符时,最好采用:当重载单目运算符时,最好采用:当重载单目运算符时,最好

12、采用:当重载单目运算符时,最好采用格式格式格式格式1 1进进进进行定义,也就是将运算符函数作为类的成员函数,行定义,也就是将运算符函数作为类的成员函数,行定义,也就是将运算符函数作为类的成员函数,行定义,也就是将运算符函数作为类的成员函数,因为因为因为因为friendfriend函数违反了类的封装。函数违反了类的封装。函数违反了类的封装。函数违反了类的封装。#include #include using namespace std;class Calculatorunsigned int value;public:Calculator()value=0;void operator +(); /

13、重载自增运算符重载自增运算符void operator -(); /重载自减运算符重载自减运算符unsigned int operator()()const; /重载括号重载括号运算符运算符;void Calculator:operator +()if(value65535)+value;else /溢出处理溢出处理coutnData overflow!0)-value;elsecoutnData overflow!endl;abort();unsigned int Calculator:operator ()()constreturn value; int main()Calculator

14、Counter;int i;for(i=0;i5;i+)+Counter; /Counter.operator+()coutnCounter=Counter();for(i=0;i5;i+)-Counter; /Counter.operator+()coutnCounter=Counter();coutendl; return 0; 当重载为成员函数时,编译器解释为:当重载为成员函数时,编译器解释为:当重载为成员函数时,编译器解释为:当重载为成员函数时,编译器解释为: ObjectLObjectL.operatoroperator op(ObjectRop(ObjectR) )左操作数由对象左

15、操作数由对象ObjectL通过通过this指针传递,指针传递,右操作数由参数右操作数由参数ObjectR传递。传递。 当重载为友元函数时,编译器解释为:当重载为友元函数时,编译器解释为:当重载为友元函数时,编译器解释为:当重载为友元函数时,编译器解释为: operator operator op(ObjectL,ObjectRop(ObjectL,ObjectR) )左右操作数都参数传递左右操作数都参数传递不管成员函数还是友元函数重载,不管成员函数还是友元函数重载,运算符的使用方法运算符的使用方法相同。相同。但由于它们但由于它们传递参数的方法不同,导致实现代码的不同,应传递参数的方法不同,导致

16、实现代码的不同,应用场合也不同用场合也不同#include using namespace std;class Vector public: Vector() Vector(int x1,int y1) x=x1;y=y1;Vector operator +(Vector v) /成员成员函数方式重载运算符函数方式重载运算符+ Vector tmp; tmp.x=x+v.x; tmp.y=y+v.y; return tmp; Vector operator -(Vector v) Vector tmp; tmp.x=x-v.x; tmp.y=y-v.y; return tmp; void di

17、splay() cout(x,y)endl;private:int x,y;int main() Vector v1(6,8),v2(3,6),v3,v4; coutv1=; v1.display();coutv2=;v2.display(); v3=v1+v2;coutv1+v2=;v3.display(); v4=v1-v2;coutv1-v2=;v4.display();return 0;#include #include class Vector()class Vector() intint x,y; x,y; public: Vector() public: Vector() Vec

18、tor(intVector(int x1,int y1) x=x1;y=y1; x1,int y1) x=x1;y=y1; friendfriend Vector operator +(Vector v1,Vector v2) Vector operator +(Vector v1,Vector v2) Vector Vector tmptmp; ; tmp.xtmp.x=v1.x+v2.x; =v1.x+v2.x; tmp.ytmp.y=v1.y+v2.y; return =v1.y+v2.y; return tmptmp; ; friend friend Vector operator -

19、(Vector v1,Vector v2) Vector operator -(Vector v1,Vector v2) Vector Vector tmptmp; ; tmp.xtmp.x=v1.x-v2.x; =v1.x-v2.x; tmp.ytmp.y=v1.y-v2.y; =v1.y-v2.y; return return tmptmp; void display() void display() coutcout(x,y)(x,y)endlendl;void main()void main() Vector v1(6,8),v2(3,6),v3,v4; Vector v1(6,8),

20、v2(3,6),v3,v4; coutcoutv1=;v1.display();v1=;v1.display(); coutcoutv2=;v2.display(); v3=v1+v2;v2=;v2.display(); v3=v1+v2; coutcoutv1+v2=;v3.display(); v4=v1-v2;v1+v2=;v3.display(); v4=v1-v2; coutcoutv1-v2=;v4.display();v1-v2=;v4.display(); 运算符也可以重载为类的友元函数,运算符也可以重载为类的友元函数,这样,它就可以自由地访问该类的任何这样,它就可以自由地访问

21、该类的任何数据成员。数据成员。 这时,运算符所需要的运算符都需要这时,运算符所需要的运算符都需要通过函数的形参表来传递,在参数表中通过函数的形参表来传递,在参数表中形参从左到右的顺序就是运算符运算数形参从左到右的顺序就是运算符运算数的顺序。的顺序。例子例子 复数运算(两个复数相加,相减)复数运算(两个复数相加,相减)class Complexdouble Real,Image;public:Complex(double r=0,double i=0);void print();friend Complex operator +(Complex &c1,Complex &c2);friend C

22、omplex operator -(Complex &c1,Complex &c2);Complex:Complex(double r,double i) Real=r;Image=i; Complex operator +(Complex &c1,Complex &c2)double r=c1.Real+c2.Real;double i=c1.Image+c2.Image;return Complex(r,i);Complex operator -(Complex &c1,Complex &c2)double r=c1.Real-c2.Real;double i=c1.Image-c2.Im

23、age;return Complex(r,i);void Complex:print()cout(Real,Image)endl; 例子例子 复数运算(两个复数相加,相减)复数运算(两个复数相加,相减)void main()Complex c1(2.5,3.7),c2(4.2,6.5),c;c=c1-c2;c.print();c=c1+c2;c.print();O赋值运算符重载用于对象数据的复制。赋值运算符重载用于对象数据的复制。O在在C+中有两种类型的赋值运算符:中有两种类型的赋值运算符:O一类是一类是“+=”和和“-=”等先计算后赋等先计算后赋值的运算符;值的运算符;O另一类是另一类是“=

24、”即直接赋值的运算符即直接赋值的运算符对于标准数据类型,对于标准数据类型,“+=”和和”-=”的作的作用是用是将一个数据与另一个数据进行加法和将一个数据与另一个数据进行加法和减法运算后减法运算后,再,再将结果回送给赋值号左边将结果回送给赋值号左边的变量中的变量中。对它们重载后,使其实现其他。对它们重载后,使其实现其他相关的功能相关的功能#include class Vectorint x,y;public:Vector();Vector(int x1,int y1)x=x1;y=y1;friend Vector operator +=(Vector v1,Vector v2) /友友元函数方式

25、实现元函数方式实现 v1.x+=v2.x;v1.y+=v2.y;return v1;Vector operator -=(Vector v) /成员函数方式实现成员函数方式实现Vector tmp;tmp.x=x-v.x;tmp.y=y-v.y;return tmp; void display()cout(x,y)endl; ;void main()Vector v1(6,8),v2(3,6),v3,v4;coutv1=;v1.display();coutv2=;v2.display();v3=v1+=v2; coutv3=v1+=v2后后,v3=;v3.display();v4=v1-=v2

26、; coutv4=v1-=v2后后,v4=;v4.display();int* pa = new int; int* pb = pa; delete pa;可以利用重可以利用重载赋值运算载赋值运算符符“”来来解决解决重载函数原型为:重载函数原型为:类型类型 & 类名类名:operator =(const 类名类名 &)编写一个日期的加天数、减天数和输出操作(不考虑编写一个日期的加天数、减天数和输出操作(不考虑闰年的情况,闰年的情况,2月份固定为月份固定为28天)天)class dateint yr,mo,da;public:date(int y,int m,int d)yr=y;mo=m;da

27、=d;date();void disp()coutyr年年mo月月da日日daysdt.mo-1)day-=daysdt.mo-1;dt.mo+;if(dt.mo=13)dt.mo=1;dt.yr+;dt.da=day;return dt;编写一个日期的加天数、减天数和输出操作(不考虑编写一个日期的加天数、减天数和输出操作(不考虑闰年的情况,闰年的情况,2月份固定为月份固定为28天)天)date date:operator -(int day) date dt=*this; day=dt.da-day;while(day=0)day+=daysdt.mo-1;dt.mo-;if(dt.mo=0

28、)dt.mo=12; dt.yr-;dt.da=day;return dt;编写一个日期的加天数、减天数和输出操作(不考虑编写一个日期的加天数、减天数和输出操作(不考虑闰年的情况,闰年的情况,2月份固定为月份固定为28天)天)#include static int days=31,28,31,30,31,30,31,31,30,31,30,31;void main()date d1(2005,1,10),d2,d3;d1.disp();d2=d1-140;d2.disp();d3=d2+140;d3.disp();编写一个日期的加天数、减天数和输出操作(不考虑编写一个日期的加天数、减天数和输出

29、操作(不考虑闰年的情况,闰年的情况,2月份固定为月份固定为28天)天)/.friend date operator +(date &dt,int day);friend date operator -(date &dt,int day);date operator +(date &dt,int day)day+=dt.da;while(daydaysdt.mo-1)day-=daysdt.mo-1; dt.mo+;if(dt.mo=13)dt.mo=1;dt.yr+;dt.da=day;return dt;date operator -(date &dt,int day)day=dt.da-d

30、ay;while(day=0)day+=daysdt.mo-1; dt.mo-;if(dt.mo=0)dt.mo=12;dt.yr-;dt.da=day;return dt;例例8-3 以非成员函数形式重载以非成员函数形式重载Complex的加的加减法运算和减法运算和“”运算符。运算符。#include class Complexpublic:Complex(double r=0.0,double i=0.0):real(r),image(i)friend Complex operator+(const Complex &c1,const Complex &c2);friend Complex

31、 operator-(const Complex &c1,const Complex &c2);friend ostream &operator (ostream &out,const Complex &c);private:double real,image;Complex operator+(const Complex &c1,const Complex &c2)return Complex(c1.real+c2.real,c1.image+c2.image);Complex operator-(const Complex &c1,const Complex &c2)return Comp

32、lex(c1.real-c2.real,c1.image-c2.image);ostream & operator (ostream &out,const Complex &c)out(c.real,c.image);return out;int main()Complex c1(5,4),c2(2,10),c3;coutc1=c1endl;coutc2=c2endl;c3=c1-c2;coutc3=c1-c2=c3endl;c3=c1+c2;coutc3=c1+c2=c3endl;return 0;例例 分析以下程序的执行结果分析以下程序的执行结果#include #include clas

33、s Samplechar *p;public:Sample(char *pn)p=new charstrlen(pn)+1; strcpy(p,pn);Sample() delete p;Sample &operator = (Sample &s) /=重载为成员函数重载为成员函数delete p; p=new charstrlen(s.p)+1;strcpy(p,s.p);return *this;void disp() coutpendl;void main() Sample list1(first object);Sample list2(second object);cout执行赋值语句之前执行赋值语句之前:endl;coutlist1 *p=; list1.disp();coutlist2 *p=; list2.disp();cout执行赋值语句之后执行赋值语句之后:endl;list2=list1;coutlist1 *p=; list1.disp();coutlist2 *p=; list2.disp();

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号