欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    《运算符重载》PPT课件.ppt

    • 资源ID:5611056       资源大小:552KB        全文页数:83页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    《运算符重载》PPT课件.ppt

    第7章 运算符重载,7.1 运算符重载概述,1、系统为基本数据类型提供了大量运算符。如:int x,y;x=x+y;表达简洁,使用方便。2、问题的提出:定义复数类。,问题的引入:,定义一个简化的复数类complex:class complex public:double real,imag;complex(double r=0,double i=0)real=r;imag=i;若要把类complex的两个对象com1和com2加在一起,下面的语句是不能实现的:main()complex com1(1.1,2.2),com2(3.3,4.4),total;total=com1+com2;/错误/return 0;,错误的原因:complex类类型不是预定义的基本数据类型,而是用户自定义的数据类型。C+知道如何相加两个int型数据,或相加两个float型数据。但是C+还无法直接将两个complex类对象相加。为了表达上的方便,人们希望能预定义的运算符在特定类的对象上也能使用,如希望能够实现total=com1+com2;这就需要重载运算符“”来解决。,这一章就学习如何将运算符作用于自定义类型的对象上:即运算符重载,运算符重载的概念,通过定义多个同名函数可以实现函数的重载。在C+语言中,运算符也被看成一种特殊的函数,也能够被重载。在前面已经接触过很多运算符重载的例子。例如:coutHello world!;cout56;在这里,同一个运算符“”,完成了两种不同类型数据的输出,这就是通过对运算符“”重载的结果。,在重载某个运算符时,就是定义一个重载运算符的函数,函数名为 operator(为要重载的运算符)。例如:operator+()operator()operator*()operator/()operator()运算符重载是通过定义函数实现的,运算符重载实质上是函数的重载(遵循函数重载的原则)。,【例7.1】用运算符重载实现复数的加运算:,#include iostream.hclass complex public:double real;double imag;complex(double r=0,double i=0)real=r;imag=i;complex operator+(complex c1,complex c2)complex c;c.real=c1.real+c2.real;c.imag=c1.imag+c2.imag;return c;,main()complex com1(1.1,2.2),com2(3.3,4.4),total1,total2;total1=operator+(com1,com2);coutreal1=total1.real imag1=total1.imagendl;total2=com1+com2;coutreal2=total2.real imag2=total2.imagendl;return 0;,换个普通函数名?,运算符重载的意义,从功能上来讲,通过运算符能实现的功能通过函数一样能够实现。也就是说运算符重载没有在程序的功能上带来好处。运算符重载可以使程序更加简洁,使表达式更加直观,增加可读性。运算符重载的使用也不宜过多,在完成同样功能的情况下,使用运算符比使用明确的函数调用能使程序更清晰,才使用运算符重载。,运算符重载规则,1.运算符重载不能改变运算符的优先级和结合性。C+语言内部已经规定了所有运算符的优先级。不论运算符作用于什么对象,该优先级都不能改变。也不能通过重载改变一个运算符的结合性。2运算符重载不能改变运算符的操作数的个数。单目运算符只能包含一个操作数,双目运算符必须有两个操作数,不能试图通过运算符重载改变操作数的个数。3运算符重载不能使用默认参数。与普通的函数重载不同,运算符重载时,不能使用默认的参数值,必须明确指出每一个操作数。,4运算符重载只能作用于自定义类型。5不能建立新的运算符。6不能改变运算符的含义。7运算符必须显式重载,不能隐式重载 例如,重载了运算符+和运算符=后,语句 obj3=obj1+obj2;是正确的,但是语句 obj1+=obj2;是不正确的。要想使该语句成立,必须显式重载运算符+=。,运算符重载函数要求至少有一个参数是类的对象。为了能操作对象的数据成员(一般为私有),在进行重载时主要采用两种方式:成员函数方式和友元函数方式。7.2.1 友元运算符函数 在C+中,可以把运算符重载函数定义成某个类的友元函数,称为友元运算符函数。,7.2 运算符重载的两种方式,1.友元运算符函数定义的语法形式 友元运算符函数的原型在类的内部声明格式如下:class X/friend 返回类型 operator运算符(形参表);/;在类外定义友元运算符函数的格式如下:返回类型 operator运算符(形参表)函数体,2.双目运算符重载 双目运算符是有两个操作数的运算符。当用友元函数重载双目运算符时,两个操作数都要传递给运算符函数。【例7.2】用友元运算符函数进行复数运算。,#include class Complex private:double real,imag;public:friend Complex operator+(Complex c1,Complex c2);friend Complex operator-(Complex c1,Complex c2);friend Complex operator*(Complex c1,Complex c2);Complex(double r=0,double i=0);void print();,Complex:Complex(double r,double i)real=r;imag=i;void Complex:print()cout0)cout+;if(imag!=0)coutimagiendl;Complex operator+(Complex c1,Complex c2)Complex temp;temp.real=c1.real+c2.real;temp.imag=c1.imag+c2.imag;return temp;,Complex operator-(Complex c1,Complex c2)Complex temp;temp.real=c1.real-c2.real;temp.imag=c1.imag-c2.imag;return temp;Complex operator*(Complex c1,Complex c2)Complex temp;temp.real=c1.real*c2.real-c1.imag*c2.imag;temp.imag=c1.real*c2.imag+c1.imag*c2.real;return temp;,main()Complex a(1,2),b(3.0,4.0),c,d,e;c=a+b;d=a-b;e=a*b;cout c=;c.print();cout d=;d.print();coute=;e.print();coutf=;f.print();return 0;,程序运行结果为:c=46id=-2-2ie=-5+10i,相当于函数调用“operator+(a,b)”,总结:设有双目运算符,如果要重载 为类的友元函数,则该友元函数也有两个参数,分别为运算符的两个运算对象。重载后,表达式oprd1 oprd2 等同于调用函数operator(oprd1,oprd2)。,3.单目运算符重载 单目运算符只有一个操作数。用友元函数重载单目运算符时,由于友元函数是外部函数,操作数都必须以参数的形式列出来。需要一个显式的操作数。【例7.3】用友元函数重载单目运算符“-”。,#include class ABpublic:AB(int x=0,int y=0)a=x;b=y;friend AB operator-(AB obj);void print();private:int a,b;AB operator-(AB obj)obj.a=-obj.a;obj.b=-obj.b;return obj;,void AB:print()couta=a b=bendl;main()AB ob1(50,60),ob2;ob1.print();ob2=-ob1;ob2.print();ob1.print();return 0;,【例7.4】使用友元函数重载“+”、“-”运算符。#include class coordpublic:coord(int i=0,int j=0)x=i;y=j;void print();friend coord operator+(coord op);private:int x,y;void coord:print()cout x:x,y:yendl;,coord operator+(coord op)+op.x;+op.y;return op;main()coord ob(10,20);ob.print();operator+(ob);ob.print();+ob;ob.print();return 0;,7.2.2 成员运算符函数 在C+中,可以把运算符函数定义成某个类的成员函数,称为成员运算符函数。当作为成员函数进行重载时,它的左操作数必须是该成员函数所属类的一个对象,因为必须通过类的对象调用该类的成员函数。,1.成员运算符函数定义的语法形式成员运算符函数的原型在类的内部声明格式如下:class X/返回类型 operator运算符(形参表);/在类外定义成员运算符函数的格式如下:返回类型 X:operator运算符(形参表)函数体,2.双目运算符重载为成员函数 对双目运算符而言,成员运算符函数的形参表中仅有一个参数,它作为运算符的右操作数。必须通过类的对象调用该类的成员函数。此时当前调用者对象作为运算符的左操作数,它是通过this指针隐含地传递给函数的。【例7.6】采用成员运算符函数来完成例7.2中同样的工作。,成员函数通过类的对象调用。成员函数中的this指针初始化为对象的首地址,通过this指针可以直接操作对象的数据成员。左操作数就是调用该运算符函数的对象。,#include class Complex public:Complex operator+(Complex c);Complex operator-(Complex c);Complex(double r=0,double i=0);void print();private:double real,imag;,Complex:Complex(double r,double i)real=r;imag=i;void Complex:print()cout0)cout+;if(imag!=0)coutimagiendl;,Complex Complex:operator+(Complex c)Complex temp;temp.real=real+c.real;temp.imag=imag+c.imag;return temp;Complex Complex:operator-(Complex c)Complex temp;temp.real=real-c.real;temp.imag=imag-c.imag;return temp;,this-real,main()Complex a(1,2),b(3.0,4.0),c,d;c=a+b;d=a-b;cout c=;c.print();cout d=;d.print();return 0;,该表达式相当于为对“+”运算符重载函数:a.operator+(b)的调用,C+规定赋值运算符“=”不重载就可以用在每一个类上。当然也可以在类的定义中提供赋值运算符重载函数。在不提供的时候,赋值运算符的默认逐个拷贝类的数据成员。,3.单目运算符重载 对单目运算符而言,成员运算符函数的参数表中没有参数,此时当前对象作为运算符的一个操作数。【例7.7】重载单目运算符“+”。,#include class coordpublic:coord(int i=0,int j=0)x=i;y=j;void print();coord operator+();private:int x,y;void coord:print()cout x:x,y:yendl;,coord coord:operator+()/coord,main()coord ob(10,20);ob.print();ob.operator+();/operator+(ob);ob.print();+ob;ob.print();return 0;,一般而言,采用成员函数重载单目运算符时,以下两种方法是等价的:aa;/隐式调用 aa.operator();/显式调用 成员运算符函数operator 所需的一个操作数由对象aa通过this指针隐含地传递。因此,在它的参数表中没有参数。,7.2.3 成员运算符函数与友元运算符函数的比较,友元函数:(1)所有的参加运算的分量必须显式地列在本友元函数的参数表中,而且这些参数类型中至少有一个是说明该友元的类或对该类的引用。(2)对双目运算符而言,友元运算符函数带有两个参数;对单目运算符而言,友元运算符函数带一个参数。,类的公有成员函数:总以当前调用者对象(*this)作为该成员函数的隐式第一运算分量。若所定义的运算多于一个运算对象时,才将其余的运算分量显式地列在该成员函数的参数表中。,成员函数和友元函数差别的关键原因:成员函数中的this指针,通常,将单目运算符重载为成员函数,将双目运算符重载为友元函数。对于运算符“=、()、”只能作为成员函数重载。双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但有一种情况,必须使用友元函数。当左操作数是内部数据类型的变量或者是其他类的对象时,必须使用友元函数进行重载。【例题7.8】内部数据类型出现在运算符的左边。,#include class ABpublic:AB(int x=0,int y=0)a=x;b=y;friend AB operator+(AB ob,int x);friend AB operator+(int x,AB ob);void show();private:int a,b;AB operator+(AB ob,int x)AB temp;temp.a=ob.a+x;temp.b=ob.b+x;return temp;,AB operator+(int x,AB ob)AB temp;temp.a=x+ob.a;temp.b=x+ob.b;return temp;void AB:show()couta=a b=bn;main()AB ob1(50,60),ob2;ob2=ob1+20;ob2.show();ob2=40+ob1;ob2.show();return 0;,7.3 几个常用运算符的重载,7.3.1 单目运算符“+”和“-”的重载 针对预定义数据类型,C+语言提供了自增运算符“+”和自减运算符“-”,这两个运算符都有两种使用方式,如下:int i=10;int x;x=i+;x=+i;,在C+中,可以通过在运算符函数参数表中是否插入关键字int来区分前缀和后缀这两种方式。(1)对于前缀方式+ob:成员函数::operator+()函数体 友元函数:operator+(类名,这里形参int是一个伪参数,仅用作区分前置还是后置,并无实际意义,可以给一个变量名,也可不给出变量名。参数int一般被传递给值0。,例:定义一个描述时间计数器的类,其中有三个数据成员分别用于存放时、分和秒。用成员函数重载“+”运算符,实现计数器对象的加1运算。,#include class TCount private:int Hour,Minute,Second;public:TCount(int h=0,int m=0,int s=0);/定义缺省值为0的构造函数 TCount operator+();/定义前置“+”运算符重载成员函数 TCount operator+(int);/定义后置“+”运算符重载成员函数 void Show(int i)/定义显示时:分:秒的成员函数 coutti=Hour:Minute:Secondendl;,TCount:TCount(int h,int m,int s)Hour=h;Minute=m;Second=s;/构造函数的实现TCount TCount:operator+()/前自增:先自增,再使用 Second+;if(Second=60)Second=0;Minute+;if(Minute=60)Minute=0;Hour+;if(Hour=24)Hour=0;return*this;,TCount TCount:operator+(int)/后自增:先使用,再自增 TCount temp=*this;Second+;if(Second=60)Second=0;Minute+;if(Minute=60)Minute=0;Hour+;if(Hour=24)Hour=0;return temp;,main()TCount t1(10,25,50),t2,t3;/定义时间计数器对象t1=10:25:50 t1.Show(1);t2=+t1;/先加后用,即:先将t1自加,然后将t1赋给t2 t1.Show(1);t2.Show(2);t3=t1+;/先用后加,即:先将t1赋给t3,然后将t1自加 t1.Show(1);t3.Show(3);return 0;,运行结果:t1=10:25:50t1=10:25:51t2=10:25:51t1=10:25:52t3=10:25:51,t1.operator+(),t1.operator+(0),0不参与任何计算。,#include class TCount private:int Hour,Minute,Second;public:TCount(int h=0,int m=0,int s=0);friend TCount operator+(TCount,例:用一个类来描述时间计数器,用三个数据成员分别存放时、分和秒。用友元函数重载“+”运算符,实现计数器对象的加1运算。,TCount:TCount(int h,int m,int s)Hour=h;Minute=m;Second=s;TCount operator+(TCount,成员函数这里是*this,为调用成员函数的当前对象,TCount operator+(TCount,main()TCount t1(10,25,50),t2,t3;/定义时间计数器对象t1=10:25:50 t1.Show(1);t2=+t1;t1.Show(1);t2.Show(2);t3=t1+;t1.Show(1);t3.Show(3);return 0;,operator+(t1),operator+(t1,0),7.3.2 赋值运算符重载,赋值运算符不用重载就可以直接用在自定义类型的对象之间,其默认的操作是逐个拷贝对象的所有数据成员。如果类的对象中包含动态分配的空间时,直接赋值就会产生问题,这时必须重载赋值运算符“=”才能正确使用。,【例7.11】使用缺省的赋值运算符函数产生错误的例子。#include#include class A char*str;public:A(char*s=no data);A();void print();A:A(char*s)int len=strlen(s);str=new charlen+1;strcpy(str,s);,1、指针悬挂的问题,(续),A:A()delete str;void A:print()cout str endl;void main()A*p=new A(AAAA);A a1;a1=*p;a1.print();delete p;a1.print();,AAAA,2.重载赋值运算符解决指针悬挂问题 重载赋值运算符,使得对目标对象数据成员指针的赋值,是把原对象指针ptr所指向的内容传递给它,而不是简单地传递指针值。,例:带有重载赋值运算符的A类,#include#include class A char*str;public:A(char*s=no data);A();A,A:A()delete str;A,void main()A*p=new A(AAAA);A a1;a1=*p;a1.print();delete p;a1.print();,程序运行结果为:AAAAAAAA,赋值运算符重载函数与复制构造函数,赋值运算符重载函数和复制构造函数都是用来把一个类的对象复制到另一个同类型的对象。然而它们被调用的时机是不同的:(1)复制构造函数是用已存在对象的各成员当前值来创建一个相同的新对象。在下述三种情况下,系统将自动调用所属类的复制构造函数。定义一个新的对象同时利用一个已有对象初始化的情况。一个对象被作为函数参数的情况。对象作为函数值进行返回的情况。(2)赋值运算符重载函数仅在赋值语句中被调用,用于把一个已存在对象的各成员的值赋值给另一个已存在的同类对象。,练习题目:阅读程序,分析下面程序的输出结果。,#include#include class String char*buffer;public:String(char*s);String()String(String,String:String(char*s)buffer=new charstrlen(s)+1;strcpy(buffer,s);String:String(String,String,*7.3.3 下标运算符“”的重载,对于一些容器类(如数组类、集合类和字符串类等),通常需要获得某个元素的值,这可以通过为类定义专门的成员函数实现,但更方便的做法是在容器类中重载下标运算符。下标运算符“”的操作数有两个:左边操作数是具有指针含义的对象,右边操作数是一个整数,用来表示下标。当有“Xn”时,具有下列含义:Xn*(X+n),运算符只能重载为成员函数,而不能重载为友元函数。一旦在类中重载了运算符,就可以将该类当做数组进行处理,可以使用下标方式来存取其中的元素。运算符的重载格式通常为:该重载函数只能有一个参数用于表示下标。运算符必须能够出现在一个赋值操作符的左、右两边。为了能在左边出现,可以把返回类型指定为一个引用。,【例】重载运算符。#include#include#include const int LIMIT=20;class MyArrayprivate:int size;/数组大小 int*array;/数组元素起始地址public:MyArray(int i=1);int,MyArray:MyArray(int i)if(iLIMIT)/数组越界检查 cout=size)/下标越界检查 cout下标越界endl;exit(1);return arrayi;,MyArray:MyArray()delete array;size=0;int main()int index;MyArray arr(5);for(int i=0;iindex;for(int i=0;iindex;i+)coutarr i=arr iendl;return 0;,对象可以像数组一样使用,7.4 类型转换,一个运算一般只操作一种数据类型,例如两个整数相加结果仍然为整数。但有时一个运算可能会涉及到多种数据类型,如整数和浮点数相加。这类运算一般都包含了数据类型之间的转换操作。C+语言规定了内部数据类型的转换规则:(1)当表达式中存在不同类型的操作数时,为对这个表达式进行求值,编译程序需要对其中的部分操作数自动进行类型转换,将它们都变换为表达式中操作数的“最大”类型,以保证运算符两边的类型是一致的,这种类型转换称为隐式类型转换。,内部数据类型的大小:Long double double float unsigned long long unsigned int int unsinged char char例:int a=4;a=a/2.5;(2)当赋值表达式左、右两边操作数的类型不一致时,右操作数首先转换为左操作数的类型,然后将转换结果赋值给左操作数,整个赋值表达式的结果类型是左操作数的类型。,(3)在函数调用时,将实参值赋给形参,系统自动隐式将实参转换成形参类型。(4)函数有返回值时,系统自动将返回表达式值转换为函数类型,赋值给调用函数。(5)也可以通过类型强制转换运算符“()”来实现内部数据类型之间的转换。两种形式:类型名(表达式)(类型名)表达式,例:已知矩形面积为20、长为8,求其宽度。语句 cout Width is:20/8 n;cout Width is:float(20)/8 n;cout Width is:(float)20/8 n;cout Width is:20/(float)8 n;cout Width is:float(20/8)n;,类型转换运算符函数,如何实现用户自定义类型和其他类型之间的转换呢?通过类型转换运算符函数实现:自定义类对象类型 别的类型的转换 通过转换构造函数实现:其他类型 自定义类型的对象 类型转换运算符函数必须为类的成员函数。其实现的一般格式为::operator()函数体 例如:operator int();/实现将自定义类型的对象转换成一个整型数据,定义转换函数时应注意如下几点:(1)转换函数必须是用户定义的成员函数,而且必须是非静态的。(2)转换函数不可以有返回值。(3)转换函数也不带任何参数。1、转换函数的名称是类型转换的目标类型,因此,不必再为它指定返回值类型;2、转换函数是被用于本类型的数值或变量转换为其他的类型,也不必带参数。,例:定义类String,并定义类型转换重载函数分别实现从类String的对象到整型和从类String的对象到字符串的转换。,#include class String friend ostream,#include String:String(const char*m)str=new charstrlen(m)+1;strcpy(str,m);String:String()delete str;ostream,istream,类型转换函数的实现,可以根据需要自行定义,String:operator char*()conststatic char temp100;strcpy(temp,);strcat(temp,str);strcat(temp,);return temp;,main()char s100;String s1,s2;couts1s2;coutoutput is:endl;couts1 is String-s1endl;couts1 as int-(int)s1endl;couts1 as char*-(char*)s1endl;cout10-s1=10-s1endl;strcpy(s,s2);coutafter strcpy(s,s2);s=sendl;return 0;,转换构造函数,类型转换运算符函数实现了从自定义类型到其他类型的转换,从其他类型到自定义类型的转换则由转换构造函数实现。转换构造函数也是构造函数的一种,其函数原型一般为:ClassName(const OtherClass obj);转换构造函数只有一个参数,就是其它类型的对象(变量),转换构造函数将根据该对象初始化自定义类型的对象。转换构造函数的实现也是根据需要定义的。其实上例中的构造函数String(const char*m=“”)就是一个转换构造函数,它根据一个字符指针类型的对象初始化类String的对象。转换构造函数也可以隐式或显式地将一种类型的对象转换成自定义类型的对象以满足运算的需要。,例:定义类String,要求类String包含两个转换构造函数,分别实现从字符串和整型数据到类String的转换。,#include class String friend ostream,/类String的实现,#include#include string.hString:String(const char*m)str=new charstrlen(m)+1;strcpy(str,m);String:String(const int len)str=new charlen+1;memset(str,a,len);strlen=0;,/类String的实现(续一),ostream,类String的实现(续二),String,测试类String,#include#include“String.h”main()String s1,s2;couts1s2;coutoutput is:endl;couts1-s1endl;couts2-s2endl;/隐式调用转换构造函数s1+=abc;coutAfter s1+=abc;s1-s1endl;s2+=10;coutafer s2+=10;s2-s2endl;,/显式调用转换构造函数cout(String)15-(String)15endl;cout(String)abc-(String)abcendl;return 0;,

    注意事项

    本文(《运算符重载》PPT课件.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开