收藏 分享(赏)

04 重载运算符.ppt

上传人:myw993772 文档编号:6922572 上传时间:2019-04-27 格式:PPT 页数:45 大小:421KB
下载 相关 举报
04 重载运算符.ppt_第1页
第1页 / 共45页
04 重载运算符.ppt_第2页
第2页 / 共45页
04 重载运算符.ppt_第3页
第3页 / 共45页
04 重载运算符.ppt_第4页
第4页 / 共45页
04 重载运算符.ppt_第5页
第5页 / 共45页
点击查看更多>>
资源描述

1、第4章 运算符重载,课件制作,2,主要内容,运算符重载的概念(13.1-13.2) 运算符重载的方法(13.3) 重载双目运算符(13.4) 重载单目运算符(13.5-13.8) 不同类型数据间的转换(13.9) 重载赋值运算符(13.11) 小结与作业,课件制作,3,4.1 运算符重载的概念,有理数类 CRational 有理数定义:由一个分子和分母组成的a/b形式的数,其中 a是分子,b为分母,如 1/3, 3/4, 10/4; 一个有理数不能以0为分母,但可以以0为分子; 每个整数a 都等价于 a/1; 有理数用于包含分数的精确运算; 有理数支持的运算有加、减、乘、除、比较; 一个有理数

2、可以转化为一个整数、浮点数或字符串;,课件制作,4,4.1 运算符重载的概念,/Rational.h #include using namespace std; /类CRational 声明 class CRational public:CRational();CRational(long numerator, long denominator);long getNumerator();long getDenominator();CRational add(CRational ,课件制作,5,4.1 运算符重载的概念,/file:Rational.cpp #include using name

3、space std; #include “Rational.h“CRational:CRational() numerator = 0;denominator = 1; CRational:CRational(long numerator, long denominator) long factor = gcd(numerator, denominator);this-numerator = (denominator 0) ? 1 : -1) * numerator / factor;this-denominator = abs(denominator) / factor; long CRat

4、ional:getNumerator() return numerator; long CRational:getDenominator() return denominator; ,课件制作,6,4.1 运算符重载的概念,CRational CRational:add(CRational ,CRational CRational:div(CRational ,课件制作,7,4.1 运算符重载的概念,string CRational:toString() char s120, s220;itoa(numerator, s1, 10); / Convert int to string s1ito

5、a(denominator, s2, 10); / Convert int to string s2if (denominator = 1)return string(s1);elsereturn string(strcat(strcat(s1, “/“), s2); /* Find GCD of two numbers */ long CRational:gcd(long n, long d) long n1 = abs(n);long n2 = abs(d);int gcd = 1;for (int k = 1; k = n1 ,课件制作,8,4.1 运算符重载的概念,/file: Rat

6、ionalTest.cpp #include using namespace std; #include “Rational.h“ int main() / Create and initialize two rational numbers r1 and r2.CRational r1(4, 2);CRational r2(2, 3);/ Test toString, add, substract, multiply, and dividecout r1.toString() “ + “ r2.toString() “ = “ r1.add(r2).toString() endl;cout

7、r1.toString() “ - “ r2.toString() “ = “ r1.sub(r2).toString() endl;cout r1.toString() “ * “ r2.toString() “ = “ r1.mul(r2).toString() endl;cout r1.toString() “ / “ r2.toString() “ = “ r1.div(r2).toString() endl;/ Test intValue and doublecout “r2.intValue()“ “ is “ r2.intValue() endl;cout “r2.doubleV

8、alue()“ “ is “ r2.doubleValue() endl;/ Test comparecout “pare(r2) is “ pare(r2) endl;cout “pare(r1) is “ pare(r1) endl;cout “pare(r1) is “ pare(r1) endl;return 0; ,能否象整数的算术运算一样,直接用“+,-,*, /”符号来实现有理数的算术运算呢?如:r3=r1+r2; 编译系统就会自动完成r1和r2两个有理数相加的运算?,课件制作,9,4.1 运算符重载的概念,重载,就是重新赋予新的含义运算符重载的实质:对已有的运算符赋予多重含义

9、运算符重载的必要性: C+中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类) 运算符重载的实现机制:将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参 编译系统对重载运算符的选择,遵循函数重载的选择原则,用“+, -,*, /”能够实现有理数的算术运算吗? 能,实现有理数算术运算的方法 重载“+, -,*, /”运算符,课件制作,10,4.2 运算符重载的方法,运算符重载的方法:在类中定义一种特殊的称为运算符函数的函数,在需要时,系统就自动调用该函数,以实现相应的运算 重载运算符的函数一般格式如下:在定义了运算符函数后,可以说函数 opera

10、tor+ 重载了运算符+,返回类型 operator 运算符 (形参表列) 对运算符的重载处理,课件制作,11,4.2 运算符重载的方法,重载运算符“+”,使之能用于两个有理数相加。,有无空格均可,/Rational.h #include using namespace std; /类CRational 声明 class CRational public:CRational operator + (CRational ,/file:Rational.cpp #include using namespace std; #include “Rational.h“ CRational CRation

11、al:operator+(CRational ,课件制作,12,4.2 运算符重载的方法,/file: RationalTest.cpp #include using namespace std; #include “Rational.h“ int main() / Create and initialize two rational numbers r1 and r2.CRational r1(4, 2);CRational r2(2, 3);CRational r;/ Test toString, operator+r = r1.operator+(r2);cout r1.toString

12、() “ + “ r2.toString() “ = “ r.toString() endl;r = r1+ r2;cout r1.toString() “ + “ r2.toString() “ = “ r.toString() endl;return 0; ,课件制作,13,4.2 运算符重载的方法,重载为类成员函数 C+预定义运算符其运算对象中至少有一个是程序员自定义类型时,需要重载运算符为该类的成员函数 重载为类成员函数时, 参数个数 = 原操作数个数 - 1(后置+、-除外) 成员函数用 this 指针隐式的访问了类的一个对象,它充当了运算符函数左边的操作数 重载为友元函数 如果需要

13、重载一个运算符,使之能够用于操作某类对象的私有成员,可以将此运算符重载为该类的友元函数 重载为友元函数时,参数个数 = 原操作数个数,且至少应该有一个自定义类型的形参,课件制作,14,4.2 运算符重载的方法,/Rational.h #include using namespace std; /类CRational 声明 class CRational public:friend CRational operator + (CRational ,将运算符“+”重载为适用于有理数加法,重载函数作为 CRational 类的友元函数,课件制作,15,4.2 运算符重载的方法,/file:Ratio

14、nal.cpp #include using namespace std; #include “Rational.h“ CRational operator+ (CRational ,课件制作,16,4.2 运算符重载的方法,/file: RationalTest.cpp #include using namespace std; #include “Rational.h“ int main() / Create and initialize two rational numbers r1 and r2.CRational r1(4, 2);CRational r2(2, 3);CRation

15、al r;/ Test toString, operator+r = operator+ (r1,r2);cout r1.toString() “ + “ r2.toString() “ = “ r.toString() endl;r = r1+ r2;cout r1.toString() “ + “ r2.toString() “ = “ r.toString() endl;return 0; ,课件制作,17,4.2 运算符重载的方法,C+不允许程序员创建新的运算符,只能对已有的C+运算符进行重载 (P321) 对于C+已有运算符,以下运算符不允许重载(5个): 成员访问运算符 . 指针取

16、内容运算符 * 作用域运算符 : 条件运算符 ? : sizeof 重载不能改变运算符运算对象(即操作数)的个数 重载不能改变运算符的优先级和结合性 重载运算符函数不能有默认参数 应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能,课件制作,18,4.2 运算符重载的方法,说明 在表达式中,如果两个操作数中其中有一个不是类对象,则重载的双目运算符(如“+”) 左侧应为类的对象如果运算符左侧的操作数属于C+标准类型,则运算符函数不能作为类的成员函数,必须声明为友元函数 C+规定:赋值运算符(=)、下标运算符()、函数调用运算符( () ) 只能重载为类的成员函数;流插入运算符“

17、”、类型转换运算符(sizeof)只能重载为类的友员函数 考虑到各方面的因素,一般将单目运算符重载为成员函数,将双目运算符重载为友元函数 由于友元的使用会破坏类的封装,从原则上说,要尽量将运算符函数作为成员函数,r = r2 + i; 表达式 i + r2,运算符左侧的操作数 i 是整数,无法调用成员函数(i.operator+ 函数),课件制作,19,4.2 运算符重载的方法,使用运算符重载能使用户程序易于编写、阅读和维护通过运算符重载,扩大了C+已有运算符的作用范围,使之能用于类对象。 运算符重载使C+具有更强大的功能、更好的可扩充性和适应性,这是C+最吸引人的特点之一,在实际工作中,类的

18、声明和类的使用往往是分离的。假如在声明CRational类时,对运算符 +,-,*, / 都进行了重载,那么使用这个类的用户在编程时可以完全不考虑函数是怎么实现的,放心大胆地直接使用 +,-,*, / 进行有理数的运算即可,十分方便。,课件制作,20,4.3 重载双目运算符,双目运算符(或称二元运算符)是C+中最常用的运算符。双目运算符有两个操作数,通常在运算符的左右两侧在重载双目运算符时,在函数中应该有两个参数,例:重载有理数类 CRational 的“ ”和“ += ”,3 + 5, a += b,i10,课件制作,21,4.3 重载双目运算符,/Rational.h #include u

19、sing namespace std; /类CRational 声明 class CRational public:bool operator (CRational ,/file:Rational.cpp #include using namespace std; #include “Rational.h“ bool CRational:operatornumerator * r2.denominator - r2.numerator*this-denominator;if ( nnumerator = this-numerator * r2.denominator + this-denomi

20、nator * r2.numerator;this-denominator = this-denominator * r2.denominator;return (*this); ,课件制作,22,4.3 重载双目运算符,/file: RationalTest.cpp #include using namespace std; #include “Rational.h“ int main() CRational r1(4, 2);CRational r2(2, 3);/ Test toString, operatorbool bRet;bRet = r1.operator(r2);cout r

21、1.toString() “ r2.toString() “ is “ int(bRet) endl; bRet = r1 r2;cout r1.toString() “ r2.toString() “ is “ int(bRet) endl; CRational r;/ Test toString, operator+=r = r1;r1.operator+=(r2);cout r.toString() “+=“ r2.toString() “ is “ r1.toString() endl;r1 = r;r1+=r2;cout r.toString() “+=“ r2.toString()

22、 “ is “ r1.toString() endl;return 0; ,课件制作,23,4.4 重载单目运算符,单目运算符只有一个操作数,如 !a,-b,&c,还有最常用的+i 和 i 等重载单目运算符时,由于单目运算符只有一个操作数,运算符重载函数只有一个参数;如果运算符重载函数作为成员函数,则还可省略此参数 运算符“-” 的重载 一元运算符作用于一个运算对象调用对象本身 一元运算符没有参数,ClassA a; +a; a+;,ClassA a, b; b=+a; b=a+;,ClassA a, b; b= -a; b= +a;,课件制作,24,4.4 重载单目运算符,/Rational

23、.h #include using namespace std; /类CRational 声明 class CRational public:CRational operator - (); private:long numerator;long denominator;static long gcd(long n, long d); ;,/file:Rational.cpp #include using namespace std; #include “Rational.h“ CRational CRational:operator- () numerator *= -1;return *t

24、his; ,课件制作,25,4.4 重载单目运算符,/file: RationalTest.cpp #include using namespace std; #include “Rational.h“ int main() / Create and initialize two rational numbers r1 and r2.CRational r2(2, 3);CRational r;/ Test toString, operator+r = r2.operator- ();cout “-“ r2.toString() “ is “ r.toString() endl;r = -r2

25、;cout “-“ r2.toString() “ is “ r.toString() endl;return 0; ,课件制作,26,4.4 重载单目运算符,+和- 运算符的重载 虽然+a 和 a+ 运算后对象a的值一致,但先自加或后自加的重载运算符函数的返回值不一致,必须在重载时予以区分 C+约定: 在自增(自减)运算符重载函数中,增加一个int 型形参,就是后置自增(自减)运算符函数 +为前置运算时,运算符重载函数的一般格式为:+为后置运算时,运算符重载函数的一般格式为:, operator +( ) , operator +(int) ; ,课件制作,27,4.4 重载单目运算符,/R

26、ational.h #include using namespace std; /类CRational 声明 class CRational public:CRational operator + ();CRational operator + (int); private:long numerator;long denominator;static long gcd(long n, long d); ;,/file:Rational.cpp #include using namespace std; #include “Rational.h“ CRational CRational:oper

27、ator+ () numerator = numerator + denominator;return *this; CRational CRational:operator+ (int) CRational temp(numerator,denominator);numerator = numerator + denominator;return temp; ,课件制作,28,4.4 重载单目运算符,/file: RationalTest.cpp #include using namespace std; #include “Rational.h“ int main() / Create a

28、nd initialize two rational numbers r1 and r2.CRational r, r1(2, 3) , r2(3,5);/ Test toString, operator+r = r1.operator+(int);cout r1.toString() “+“ “ is “ r.toString() endl;r = r1+;cout r1.toString() “+“ “ is “ r.toString() endl;r = r2.operator+();cout “+“ r2.toString() “ = “ r.toString() endl;r =+

29、r2;cout “+“ r2.toString() “ = “ r.toString() endl;return 0; ,课件制作,29,4.4 重载单目运算符,/file: Increase.h #include using namespace std; class Increase public:Increase(int x):value(x)Increase ,/file: Increase.cpp #include “Increase.h“ Increase /返回原有对象值 ,课件制作,30,4.4 重载单目运算符,/file: IncreaseTest.cpp #include u

30、sing namespace std; #include “Increase.h“ int main() Increase n(20);n.display();(n-).display(); /显示临时对象值n.display(); /显示原有对象-n;n.display();-(-n);n.display();(n-)-; /第二次减量操作对临时对象进行n.display();return 1; ,n-t1; n=n-1; n-t2; n=n-1;,课件制作,31,4.4 重载单目运算符,运算符重载 C+中,数组下标符号被视为运算符 必要时可以重载此运算符以实现象访问数组一样访问对象内容,使

31、用 r0 和 r1 语法形式访问有理数 r 的分子分母,/Rational.h #include using namespace std; /类CRational 声明 class CRational public:long ,/file:Rational.cpp #include using namespace std; #include “Rational.h“ long ,课件制作,32,4.4 重载单目运算符,/file: RationalTest.cpp #include using namespace std; #include “Rational.h“ int main() CR

32、ational r(2, 3);/ Test toString, operatorcout “r is “r.toString() endl; cout “r0 is “ r0 “,r1 is “r1 endl; r0 = 5;r1 = 6;cout “r is “r.toString() endl; cout “r0 is “ r.operator(0) “,r1 is “r1 endl; return 0; ,课件制作,33,4.4 重载单目运算符, 运算符重载 是类 istream 的成员(ostream 是C+标准类库中用于处理输出的类, istream 是C+标准类库中用于处理输入的

33、类) C+允许重载 (流提取运算符),用于从输入流读取对象内容; 运算符和不是类CRational 的成员,同时重载时又需要访问类CRational 的私有成员,因此可将其声明为类CRational 的友元,课件制作,34,4.4 重载单目运算符,/Rational.h #include #include using namespace std; /类CRational 声明 class CRational public:friend ostream,课件制作,35,4.4 重载单目运算符,/file:Rational.cpp #include using namespace std; #in

34、clude “Rational.h“ ostream ,课件制作,36,4.4 重载单目运算符,/file: RationalTest.cpp #include using namespace std; #include “Rational.h“ int main() CRational r1,r2;coutr1;coutr2;cout“r1 + r2 is “r1.add(r2) endl;return 0; ,课件制作,37,4.5 不同类型数据间的转换,标准类型数据间的转换 隐式类型转换:在C+中,某些不同类型数据之间可以自动转换,这种转换是由C+编译系统自动完成的,用户不需干预显式类型

35、转换:程序人员在程序中指定将一种指定的数据转换成另一指定的类型,其形式为:类型名(数据)或 (类型名)数据用户自己声明的类型 编译系统并不知道怎样进行转换,解决这个问题需要定义专门的函数来处理即转换运算符函数,让编译系统知道怎样去进行这些转换 转换运算符函数就是在类中定义一个成员函数,将类转换为某种期望的数据类型,int i = 6; i = 7.5 + i; / i is 13,int i = int(89.5) ; / or (int) 89.5 , i is 89; (short int) 89.8,课件制作,38,4.5 不同类型数据间的转换,转换运算符函数语法格式为:转换运算符函数必

36、须是类的成员,对转换运算符函数的调用是隐含的,没有参数 转换运算符函数没有返回值,函数名就是所期望的将对象转换为的目标类型,ClassName : operator ( ) . ,欲转换类型,关键字,类名,具体的转换算法,课件制作,39,将类 CRational 转换为 int 型和 double型,4.5 不同类型数据间的转换,/Rational.h #include #include using namespace std; /类CRational 声明 class CRational public:operator int();operator double(); private:lon

37、g numerator;long denominator;static long gcd(long n, long d); ;,/file:Rational.cpp #include using namespace std; #include “Rational.h“ CRational:operator int () return numerator/denominator; CRational:operator double () return 1.0*numerator/denominator; ,课件制作,40,4.5 不同类型数据间的转换,/file: RationalTest.cp

38、p #include using namespace std; #include “Rational.h“ int main() CRational r1(9,4);cout“ r1 is “ r1endlint i = r1+3;cout“ r1 + 3 is “ iendl; double f = r1 + 1.25;cout“ r1 + 1.25 is “ fendl;return 0; ,课件制作,41,4.6 重载赋值运算符,默认情况下,赋值运算符(=) 执行从一个对象到另一个对象的逐成员拷贝(浅拷贝)当对象的成员中使用了动态数据类型时(用 new 开辟空间),就不能直接相互赋值,否

39、则在程序的执行期间会出现运行错误 自定义拷贝构造函数不会改变赋值拷贝运算符 = 的默认行为 为了改变默认赋值运算符( =) 的工作方式,需要重载 赋值 运算符(=),CRational r1(1,2); CRational r2(3,4);r2 = r1; cout“r1 is “ r1endl; cout“r2 is “r2endl;,课件制作,42,4.6 重载赋值运算符,/file:ClassA.h #include using namespace std; class ClassA public: ClassA( ) ps=NULL;ClassA(char *s ) ;ClassA(

40、);void Show(); private:char *ps; ;,/ file: ClassA.cpp #include using namespace std; #include “ClassA.h“ ClassA:ClassA(char *s )ps =new char strlen(s)+1; strcpy(ps,s);/psstrlen(s)+1=0; ClassA:ClassA( ) if (ps) delete ps; void ClassA:Show() coutpsendl; ,#include “ClassA.h“ int main( ) ClassA s1(“China

41、!“);ClassA s2(“Computer!“);s1.Show(); s2.Show(); s2=s1; s1.Show(); s2.Show();return 0; ,课件制作,43,4.6 重载赋值运算符,重载赋值运算符“”,即重新定义“”的格式为: 赋值运算符必须重载为成员函数, :operator=(),/file:ClassA.h #include using namespace std; class ClassA public: ClassA( ) ps=NULL;ClassA(char *s ) ;ClassA( );ClassA ,/ file: ClassA.cpp #

42、include using namespace std; #include “ClassA.h“ ClassA ,返回同种类型的引用适合于连续赋值,课件制作,44,s2.ps重新开辟内存,存放“China”,#include “ClassA.h“ int main( ) ClassA s1(“China!“),s2(“Computer!“),s3;s1.Show(); s2.Show(); s3=s2=s1; /s2.operator=(s1);s1.Show(); s2.Show();s4.Show();return 0; ,4.6 重载赋值运算符,课件制作,45,小结与作业,本章要求 理解重定义与类有关的运算符; 理解重载运算符的规则; 掌握重载运算符的方法; 掌握双目运算符、单目运算符及赋值运算符的重载; 掌握将一个类对象转换为另一个类对象的方法 思考与作业 作业(P334):13.1,13.5 预习实验指导书第4章,预习教材第14 章,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报