第4章运算符重载剖析

上传人:今*** 文档编号:107867381 上传时间:2019-10-21 格式:PPT 页数:78 大小:869KB
返回 下载 相关 举报
第4章运算符重载剖析_第1页
第1页 / 共78页
第4章运算符重载剖析_第2页
第2页 / 共78页
第4章运算符重载剖析_第3页
第3页 / 共78页
第4章运算符重载剖析_第4页
第4页 / 共78页
第4章运算符重载剖析_第5页
第5页 / 共78页
点击查看更多>>
资源描述

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

1、面向对象 第4章 运算符重载,2,主要内容,运算符重载的目的、定义和实质 运算符重载的规则 运算符重载的两种形式 友元的作用和定义 类型转换运算符重载,3,提出问题,复数的加减运算问题: 对于非基本数据类型,如复数、分数,如何在程序中进行运算? 能否直接用运算符(+、-、*、/)进行运算?,4,分析问题,自定义一个复数类Complex完成复数的加减运算 设计复数类 class Complex /复数类 public: Complex(double r=0.0,double i=0.0) /构造函数 real=r; image=i; private: double real, image; /定

2、义实部、虚部 ;,5,思考,是否能通过下面的代码完成复数的加减运算: int main() /定义一个复数对象c1,其实部为2,虚部为2.5 Complex c1(2, 2.5); Complex c2(3, 1.4); Complex c3, c4; c3 = c1 + c2; c4 = c1 - c2; return 0; ,6,说明,C+预定义的“+”、“-”运算只支持基本数据类型,并不支持用户自定义类型。 复数类的加减运算不能采用系统预定义的运算符“+”、“-”完成,那么编写成员函数来实现加、减运算。,7,重新设计复数类Complex,class Complex public: Com

3、plex(double r=0.0,double i=0.0) /构造函数 real=r; image=i; double Real()return real; /返回复数的实部 double Imag()return image;/返回复数的虚部 Complex add(Complex ,8,完成复数与复数相加 Complex Complex:add(Complex ,成员函数定义,9,完成复数与实数相加 Complex Complex:add(double d) Complex temp; temp.real = real + d; temp.image = image; return t

4、emp; ,10,int main() Complex c1(2, 2.5); Complex c2(3, 1.4); Complex c3, c4; c3=c1.add(c2); c4=c1.sub(c2); cout“c3= “c3.Real() “ +i “c3.Imag()endl; cout“c4= “c4.Real()“ +i “c4.Imag()endl; return 0; ,不如c3=c1+c2直观!,11,用函数的方式将复数的加减运算表示出来远不如用运算符“+”、“-”直观 如果复数的运算能够用已有的运算符表示出来,则程序的易读性会大大增强,同时更符合人的思维习惯 C+提供

5、了运算符重载机制,使得系统预定义的运算符能够完成用户自定义数据类型的运算,说明,12,运算符重载,运算符重载就是为用户自定义类型重新定义运算符,使同一个运算符既可以作用于预定义的数据类型,也可以作用于用户自定义的数据类型。 运算符重载本质上是一种特殊的函数重载。,13,运算符重载,为了重载运算符,必须定义一个运算符重载函数,由这个函数来完成该运算符应该完成的操作。运算符的操作数通常是类的对象。 可以将运算符重载函数作为类的成员函数或者是友元函数。,14,重载为类的成员函数,格式如下: operator () 函数体 ,A operator + (A ,/重载了类A的“+”运算符,返回类型,运算

6、的对象,关键字,函数名,运算的对象,15,在复数类中重载运算符,class Complex /复数类 public: Complex(double r=0.0,double i=0.0)real=r;image=i; const double Real()return real; const double Imag()return image; Complex operator+( Complex ,16,运算符重载为成员函数时最多有一个形参 运算符重载的实质就是函数重载,只不过函数名换成了关键字operator和具体要重载的运算符 运算符重载的函数参数就是该运算符涉及的操作数,因此运算符重载

7、在参数个数上是有限制的,这是它不同于函数重载之处。,说明,17,class A int i; public:A(int a=0) i=a; void Show(void) cout“i=“iendl; void AddA(A ,没有重载运算符的例子,利用函数完成了加法运算,用和作对象调用函数,18,class A int i; public:A(int a=0) i=a; void Show(void) cout“i=“iendl; void AddA(A ,相当于a3=a1.operator+(a2),有重载运算符的例子,19,重载运算符与一般成员函数的比较:,相同:1)均为类的成员函数;2

8、)实现同一功能,void AddA(A ,A operator +(A ,a3=a1+a2;,a3.AddA(a1,a2);,返回值,函数名,形参列表,由对象a3调用,函数调用:,返回值,函数名,形参,函数调用:,a3=a1.operator+(a2);,由对象a1调用,20,A operator +(A ,a3=a1+a2;,返回值,函数名,形参,函数调用:,a3=a1.operator+(a2);,由对象a1调用,总结:,运算符重载为成员函数时,左操作数必须是对象本身,由左操作数调用右操作数。最后将函数返回值赋给运算结果的对象。,21,运算符重载的规则,重载的功能应当与原有功能类似,不能改

9、变原运算符的操作数个数,同时至少要有一个操作数的类型是自定义类型。 重载之后运算符的优先级和结合性都不会改变,并且要保持原运算符的语法结构。参数和函数值类型都可以重新说明。,22,运算符重载的规则,当用成员函数实现运算符的重载时,运算符重载函数的参数只能有两种情况:没有参数或带有一个参数。 在重载单目运算符时,通常不能有参数;在重载双目运算符时,只能带有一个参数。参数可以是对象,对象的引用,或其它类型的参数。 在C+中不允许重载有三个操作数的运算符。,23,不能重载的运算符,24,单目运算符的重载,只具有一个操作数的运算符为单目运算符,最常用的为及。,A a, b; b=+a; b=a+;,A

10、 a; +a; a+;,可以看出,虽然运算后对象a的值一致,但先自加或后自加的重载运算符函数的返回值不一致,必须在重载时予以区分。,25,+为前置运算符时,它的运算符重载函数的一般格式为: operator +( ) +为后置运算副时,它的运算符重载函数的一般格式为: operator +(int),A a, b; b=+a; b=a+;,A operator +( ) ,A operator +(int) ,26,class A float x, y; public: A(float a=0, float b=0) x=a; y=b; A operator +( )A t; t.x=+ x;

11、 t.y=+y; return t; A operator +(int) A t; t.x=x+; t.y=y+; return t; ; int main() A a(2,3), b; b=+a; b=a+; return 0; ,27,A operator +( ) A t; t.x=+ x; t.y=+y; return t; ,b=+a;,b=a.operator+( );,返回值,函数名,a,t,3,3,4,4,t作为函数值返回赋给b,A operator +( ) + x; +y; return *this; ,将对象本身作为函数值返回赋给b,28,A operator +(int

12、) A t; t.x=x+; t.y=y+; return t; ,b=a+;,b=a.operator+(3);,a,t,3,2,4,3,返回值,函数名,t作为函数值返回赋给b,29,运算符重载为成员函数后,它可以自由地访问类的所有成员。实际使用时,总是通过该类的某个对象来访问重载的运算符。 运算符重载为类的成员函数时,函数的参数个数比原来操作数少一个(后置“+”和后置“-”除外)。,说明,30,用成员函数实现运算符的重载时,运算符的左操作数为当前对象,并且要用到隐含的this指针。 运算符重载函数不能定义为静态的成员函数,因为静态的成员函数中没有this指针。,说明,31,说明,如果是双目

13、运算符,左操作数一定是对象本身,由this指针给出,另一个操作数需要由运算符重载的参数表来传递。 如果是单目运算符,操作数由对象的this指针给出,就不再需要任何参数。但重载“+”和“-”运算符时,C+约定,如果在参数表中放一个整型参数,则表示重载的运算符为后缀运算符。,32,根据类的封装性,一般将数据成员声明为私有成员,外部不能直接访问,只能通过类的公有成员函数对私有成员进行访问。 C+从高效的角度出发,提供友元机制,使被声明为友元的全局函数或者其他类可以直接访问当前类中的私有成员,又不改变其私有成员的访问权限。,友元,33,友元可以是一个全局函数、另一个类的成员函数或者是一个类。分别称为友

14、元函数和友元类。友元类的所有成员函数都是友元函数,可以访问被访问类的任何成员。 友元声明以关键字friend开始,只能出现在被访问类的定义中。具体格式如下: friend (); friend class ;,友元,34,友元函数不是成员函数,用法也与普通的函数完全一致,只不过它能访问类中所有的数据。友元函数破坏了类的封装性和隐蔽性,使得非成员函数可以访问类的私有成员。 一个类的友元可以自由地用该类中的所有成员。,友元,35,class A float x,y; public: A(float a, float b) x=a; y=b; float Sum() return x+y; frie

15、nd float Sum(A ,友元函数,成员函数,友元函数的调用,直接调用,成员函数的调用,利用对象名调用,友元函数只能用对象名引用类中的数据。,私有数据,36,友元函数与普通函数,友元函数近似于普通的函数,它不带有this指针,因此必须将对象名或对象的引用作为友元函数的参数,这样才能访问到对象的成员。 友元函数必须在类的定义中声明,其函数体可在类内定义,也可在类外定义。 友元函数可以访问该类中的所有成员(公有的、私有的和保护的),而一般函数只能访问类中的公有成员。,37,class A float x,y; public: A(float a, float b) x=a; y=b; float Getx() return x; float Gety() return y; float Sum() return x+y; friend float Sum(A ,成员函数,友元函数,可以直接调用类中私有成员,普通函数,必须通过公有函数访问私有成员,对象调用成员函数,调用友元函数,调用普通函数,友元函数,38,友元函数不受类中访问权限关键字的限制,可以把它放在类的私有、公有或保护部分,其作用都是一样的。换言之,在类中对友元函数指定访问权限是不起作用的。 友元函数的作用域与普通函数的作用域相同。 谨慎使用友元函数 通常使用友元函数来取对象中的数据成员

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

最新文档


当前位置:首页 > 高等教育 > 大学课件

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