《第8讲 运算符重载精选文档.ppt》由会员分享,可在线阅读,更多相关《第8讲 运算符重载精选文档.ppt(38页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第8讲 运算符重载本讲稿第一页,共三十八页Contents 8.1 概述概述18.2 运算符重载的一般规则运算符重载的一般规则28.3 运算符重载的两种形式运算符重载的两种形式38.4 几个常用运算符的重载几个常用运算符的重载4本讲稿第二页,共三十八页8.1 概述概述在在C+中,同一个运算符中,同一个运算符“+”可以完成不同类型的数据运算。可以完成不同类型的数据运算。C+语言针对基本数据类型已经对某些运算符做了运算符重载,语言针对基本数据类型已经对某些运算符做了运算符重载,由由编译程序自动完成编译程序自动完成的,无需程序员进行任何操作。的,无需程序员进行任何操作。然而,在解决各种各样的实际问题
2、时往往需要使用许多自定然而,在解决各种各样的实际问题时往往需要使用许多自定义的数据类型。这些自定义类型的重载必须由程序员自己完义的数据类型。这些自定义类型的重载必须由程序员自己完成。成。本讲稿第三页,共三十八页l例如,在解决科学计算问题时常要用到复数的运算,下面定义一个简例如,在解决科学计算问题时常要用到复数的运算,下面定义一个简化的复数类化的复数类complex:class complex double real,imag;complex(double r=0,double i=0)real=r;imag=i;l如果定义类如果定义类complex的两个对象的两个对象c1和和c2,再把,再把c
3、1和和c2加在一起,这加在一起,这样的运算能不能实现呢?答案是否定的。样的运算能不能实现呢?答案是否定的。void main()complex c1(1.1,2.2),c2(3.3,4.4),total;total=c1+c2;/编译错误编译错误本讲稿第四页,共三十八页【例例8.1】使用成员函数完成复数的加法运算。使用成员函数完成复数的加法运算。#include class complex/complex类声明类声明private:double x,y;/实部为实部为x,虚部为,虚部为ypublic:complex(double xx=0,double yy=0)/构造函数构造函数 x=xx;
4、y=yy;double getx()/得到实部得到实部x值值 return x;double gety()/得到虚部得到虚部y值值return y;本讲稿第五页,共三十八页void display()/输出复数输出复数cout(0)cout+y*i);else if(y0)couty*i);else coutx=c1.x+c2.x;this-y=c1.y+c2.y;return*this;void main()complex c1(3,4),c2(4,-5),c3;c3.add(c1,c2);c1.display();cout+;c2.display();cout=;c3.display();
5、cout endl;程序运行结果:程序运行结果:(3+4*i)+(4-5*i)=(7-1*i)本讲稿第六页,共三十八页只能重载只能重载C+中已经存在的运算符,不许定义新运算符。中已经存在的运算符,不许定义新运算符。不能改变运算符的语法结构,即操作数的个数。不能改变运算符的语法结构,即操作数的个数。不能改变不能改变C+语言中已定义的运算符的优先顺序和结合性。语言中已定义的运算符的优先顺序和结合性。一般不改变运算符功能。一般不改变运算符功能。不能重载的运算符:不能重载的运算符:sizeof();成员运算符;成员运算符(.);指向成员的指针;指向成员的指针运算符运算符(*);作用域运算符;作用域运算
6、符(:);条件运算符;条件运算符(?:)。必须和用户自定义的类对象一起使用,其参数至少应有一个是类的对象或必须和用户自定义的类对象一起使用,其参数至少应有一个是类的对象或对象的引用。对象的引用。重载运算符函数不能含有默认的参数。重载运算符函数不能含有默认的参数。运算符只能被显式重载。运算符只能被显式重载。8.2 运算符重载规则运算符重载规则本讲稿第七页,共三十八页8.3.1 用成员函数重载运算符8.3.2 用友元函数重载运算符 returnreturn本讲稿第八页,共三十八页1、重载为成员函数、重载为成员函数函数类型函数类型 类名类名:operator 运算符(参数表)运算符(参数表)函数体函
7、数体;其中,其中,“函数类型函数类型”是成员函数的返回值类型;是成员函数的返回值类型;“类名类名”是重是重载该运算符的类;载该运算符的类;“operator”是关键字,是重载运算符标志;是关键字,是重载运算符标志;“运运算符算符”是要重载的运算符;是要重载的运算符;“参数表参数表”表示该运算符所需要的操作数,二表示该运算符所需要的操作数,二元运算符重载为类的成员函数,它们包含一个形参,即运算符右侧的操作元运算符重载为类的成员函数,它们包含一个形参,即运算符右侧的操作数。数。注意:注意:要重载的运算符必须置于关键字要重载的运算符必须置于关键字operator之后。之后。8.3 运算符重载形式运算
8、符重载形式本讲稿第九页,共三十八页【例例8.2】用成员函数重载算术运算符用成员函数重载算术运算符“+”。#include class complex private:double x,y;public:complex(double xx=0,double yy=0)x=xx;y=yy;double getx()return x;double gety()return y;void display()cout(0)cout+y*i);else if(y0)couty*i);else coutx+c1.x;/不要不要this可以吗?可以吗?c.y=this-y+c1.y;return c;void
9、 main()complex c1(3,4),c2(4,-5),c3;c3=c1+c2;/使用重载的运算符使用重载的运算符“+”c1.display();cout+;c2.display();cout=;c3.display();cout endl;程序运行结果:程序运行结果:(3+4*i)+(4-5*i)=(7-1*i)本讲稿第十一页,共三十八页 现在可以使用以下语句将对象进行加操作:obj3=obj1+obj2;/类complex 对象 运算符“+”可以访问两个对象:运算符左侧对象obj1是将要调用重载运算符函数的对象,右侧对象obj2作为函数调用的参数,也就是说编译程序将其解释为obj3
10、=obj1.operator+(obj2)的形式。由此可见,当重载为成员函数时,双目运算符仅有一个参数。对于单目运算符,重载为成员函数时,不需要再说明参数。重载为成员函数时,总是隐含了一个参数,该参数是this指针。this指针是指向调用该成员函数对象的指针。本讲稿第十二页,共三十八页 运算符重载为类的友元函数的一般语法形式如下:friend 函数类型 operator 运算符(形参表)函数体;其中:“friend”是运算符重载为友元函数时,在函数类型说明之前使用的关键字。二元运算符重载作为友元函数,它们含有两个参数。8.3.2 用友元函数重载运算符本讲稿第十三页,共三十八页【例8.3】用友元
11、函数重载关系运算符!=。#include class complex /complex类声明private:double x,y;/实部为x,虚部为ypublic:complex(double xx=0,double yy=0)/构造函数x=xx;y=yy;double getx()/得到实部x值return x;本讲稿第十四页,共三十八页double gety()/得到虚部y值return y;void display()cout(0)cout+y*i);else if(y0)couty*i);else coutendl;friend bool operator!=(complex&c1,c
12、omplex&c2);bool operator!=(complex&c1,complex&c2)bool c;c=(c1.x!=c2.x)|(c1.y!=c2.y);return c;本讲稿第十五页,共三十八页void main()complex c1(3,4),c2(4,3);bool b;b=c1!=c2;c1.display();cout!=;c2.display();b?cout is True.endl:cout is False.endl;cout、=运算符时,运算符函数必须声明为类的成员函数。本讲稿第二十三页,共三十八页2重载为类的友元函数 单目运算符重载为类的成员函数时,不能
13、再显示说明参数。因为重载为类的成员函数时总是隐藏了一个参数,该参数就是this指针。this指针是指向调用该成员函数对象的指针。当重载为类的友元函数时,由于不存在隐含的this指针,对单目运算符来说,友元函数有一个参数。【例8.5】用友元函数重载运算符+。#include iostream.hclass Pointprivate:int xcoord;int ycoord;public:Point()xcoord=0;ycoord=0;本讲稿第二十四页,共三十八页Point(int x,int y)xcoord=x;ycoord=y;void display()cout“(”xcoord”,”
14、ycoord”)”endl;friend Point operator+(Point&);/前缀自增friend Point operator+(Point&,int);/后缀自增;Point operator+(Point&e)return Point(+e.xcoord,+e.ycoord);Point operator+(Point&e,int)return Point(e.xcoord+,e.ycoord+);本讲稿第二十五页,共三十八页void main()Point p1(10,10),p2;p2=p1+;p1.display();p2.display();p2=+p1;p1.di
15、splay();p2.display();两种运算符重载形式的比较:一般情况下,单目运算符常使用成员函数形式重载运算符,而双目运算符常使用友元函数形式进行运算符重载。当需要重载运算符具有可交换性时,选择重载为友元函数更为适宜。程序运行结果为:程序运行结果为:(11,11)(10,10)(12,12)(12,12)returnreturn本讲稿第二十六页,共三十八页1双目算术运算符重载 双目运算符重载为类的成员函数,它们包含一个形参,即运算符右侧的值。例如,当要完成obj1+obj2时,重载运算符+为成员函数的声明为:Example operator+(Example obj2)作为友元函数,它
16、们含有两个参数。例如:friend Example operator+(Example obj1,Example obj2)需要两个操作数进行运算。【例8.6】重载算术运算符“*”。#include class complex /complex类声明private:double x,y;/实部为x,虚部为y8.4.2 双目运算符重载本讲稿第二十七页,共三十八页public:complex(double xx=0,double yy=0)/构造函数x=xx;y=yy;double getx()/得到实部x值return x;double gety()/得到虚部y值return y;本讲稿第二十八
17、页,共三十八页void display()cout(0)cout+y*i);else if(y0)couty*i);else coutendl;friend complex operator*(complex&c1,complex&c2);complex operator*(complex&c1,complex&c2)complex c;c.x=c1.x*c2.x-c1.y*c2.y;c.y=c1.x*c2.y+c1.y*c2.x;return c;本讲稿第二十九页,共三十八页void main()complex c1(3,4),c2(5,10),c3;c3=c1*c2;/使用友元函数重载的运
18、算符*c1.display();cout*;c2.display();cout=;c3.display();coutendl;程序运行结果为:(3+4*i)*(5+10*i)=(-25+50*i)本讲稿第三十页,共三十八页2重载比较和逻辑运算符 比较和逻辑运算符是双目运算符,双目运算符需要两个对象才能进行比较。可重载的比较运算符包括,=,=和!=。可重载的逻辑运算符包括&和|。例如:int String:operator(String ss)return(strcmp(str,ss.str);【例8.7】用成员函数重载关系运算符“=”。#include iostream.hclass comp
19、lex /complex类声明private:double x,y;/实部为x,虚部为y本讲稿第三十一页,共三十八页public:complex(double xx=0,double yy=0)/构造函数x=xx;y=yy;double getx()/得到实部x值return x;double gety()/得到虚部y值return y;本讲稿第三十二页,共三十八页void display()cout(0)cout+y*i);else if(y0)couty*i);else coutendl;bool operator=(complex&c1);bool complex:operator=(c
20、omplex&c1)bool b;b=x*x+y*y=c1.x*c1.x+c1.y*c1.y;return b;本讲稿第三十三页,共三十八页void main()complex c1(33,24),c2(45,-15);bool bl;bl=c1=c2;/使用重载的运算符c1.display();cout=;c2.display();bl?cout is True.endl:cout is False.endl;程序运行结果为:程序运行结果为:(33+24*i)=(45-15*i)is True.本讲稿第三十四页,共三十八页3重载赋值运算符 如果数据成员包含指针且已经使用运算符new分配内存,
21、默认赋值运算符仅将源对象逐字节复制到目的对象。【例8.8】重载赋值运算符“=”。#include class CPoint private:long x,y;public:CPoint(long x1=0,long y1=0)x=x1;y=y1;CPoint operator=(CPoint p);void print()cout(x ,y)endl;本讲稿第三十五页,共三十八页CPoint CPoint:operator=(CPoint p)x=p.x;y=p.y;return p;void main()CPoint p1(10,10),p2(20,20);cout赋值前:endl;coutp1:;p1.print();coutp2:;p2.print();p1=p2;cout赋值后:endl;coutp1:;p1.print();coutp2:;p2.print();程序运行结果为:程序运行结果为:赋值前:赋值前:p1:(:(10,10)p2:(:(20,20)赋值后:赋值后:p1:(:(20,20)p2:(:(20,20)本讲稿第三十六页,共三十八页本讲稿第三十七页,共三十八页本讲稿第三十八页,共三十八页