第4章运算符重载ppt课件.ppt

上传人:牧羊曲112 文档编号:1428528 上传时间:2022-11-23 格式:PPT 页数:75 大小:118KB
返回 下载 相关 举报
第4章运算符重载ppt课件.ppt_第1页
第1页 / 共75页
第4章运算符重载ppt课件.ppt_第2页
第2页 / 共75页
第4章运算符重载ppt课件.ppt_第3页
第3页 / 共75页
第4章运算符重载ppt课件.ppt_第4页
第4页 / 共75页
第4章运算符重载ppt课件.ppt_第5页
第5页 / 共75页
点击查看更多>>
资源描述

《第4章运算符重载ppt课件.ppt》由会员分享,可在线阅读,更多相关《第4章运算符重载ppt课件.ppt(75页珍藏版)》请在三一办公上搜索。

1、第四章 运算符重载,C+面向对象程序设计,2,本章主要内容,4.1 什么是运算符重载4.2 运算符重载的方法4.3 重载运算符的规则4.4 运算符重载函数作为类成员函数和友元函数,4.5 重载双目运算符4.6 重载单目运算符4.7 重载流插入运算符和流提取运算符4.8 不同类型数据间的转换,3,【目的要求】 1、掌握运算符重载的基础知识。 2、掌握运算符重载函数为类成员函数及友元函数的方法。3、熟悉不同类型数据间的转换。【重点】 运算符重载的方法;运算符重载函数作为类成员函数;运算符重载函数作为友元函数;单目运算符重载;不同类型数据之间的转换。【难点】 单目运算符重载函数;不同类型数据间的转换

2、。,4,4.1 什么是运算符重载 函数的重载 所谓函数的重载是指完成不同功能的函数可以具有相同的函数名。 C+的编译器是根据函数的实参来确定应该调用哪一个函数的。 运算符重载 就是赋予已有的运算符多重含义。C+通过重新定义运算符,使它能够用于特定类的对象执行特定的功能,5,例如:“”是右移运算符,但在输入操作中又是与流对象cin配合使用的流提取运算符。 因此,如果程序中用“”作流插入运算符和流提取运算符,必须在本文件模块中包含头文件iostream。 例4.1 没有用运算符重载,通过函数来实现两个复数相加。,6,#include using namespace std;class Comple

3、x public: Complex( )real=0;imag=0; /定义构造函数 Complex(double r,double i) real=r;imag=i; Complex complex_add( Complex ,7,Complex Complex:complex_add(Complex ,8,int main( ) Complex c1(3,4),c2(5,-10),c3; c3=plex_add(c2); /调用复数相加函数 coutc1=; c1.display(); coutc2=; c2.display(); coutc1+c2=; c3.display(); ret

4、urn 0;,9,运算结果是正确的。但能否进行: c3=c1+c2; 的运算呢?4.2 运算符重载的方法 运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数。即:运算符重载实质上是函数的重载。重载运算符的一般格式为:函数类型 operator 运算符名称 (形参表列) 对运算符的重载处理 ,10,例如:想将“+”用于Complex类(复数)的加法运算,函数的原型可以是:Complex operator+ (Complex 其中: operator是关键字,是专门用于定义重载运算符的函数的;运算符名称就是C+提供给用户的预下定义运算符。 注意:函数名是由

5、operator和运算符组成,即上面的operator+ 就是函数名,意思是:对运算符+重载。,11,定义了重载运算符的函数后,可出说:函数operator+重载了运算符+。如执行到复数相加:c3=c2+c1;时,系统就会调用operator+函数,把c1和c2作为实参。 怎样理解运算符重载函数?对于普通函数,参数出现在圆括号内,而对于运算符重载函数,参数出现在其左、左两侧。 例4.2 重载运算符“+”,使之能用于两个复数对象的相加。,12,#include using namespace std;class Complex public: Complex()real=0;imag=0; /默

6、认构造函数(没有参数) Complex(double r,double i)real=r;imag=i; /构造函数重载(有两个参数) Complex operator + (Complex ,13,Complex Complex:operator + (Complex ,14,int main( ) Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; /运算符+用于复数运算 coutc1=;c1.display( ); coutc2=;c2.display( ); coutc1+c2=;c3.display( ); return 0; 请比较例4.1与例4.2的不

7、同。,15,说明:C+编译系统将程序中的表达式c1+c2解释为: c1. operator+ (c2 ) /c1和c2是Complex类的对象 即:以c2为实参调用c1的运算符重载函数operator + (Complex &c2) ,进行求值,得到两个复数之和。 operator + 是一个函数名,它是类Complex的成员函数(关于运算符重载函数用作类的成员函数,4.4节将继续介绍)。 对于上面例子中的运算符重载函数operator + 还可以写成:,16,Complex Complex:operator + (Complex 参见:C4-2-2.CPP return语句是建立一个临时对象

8、,它没有名字,是一个无名对象。在建立临时对象过程中调用构造函数。 return语句将此临时对象作为函数返回值,17,4.3 重载运算符的规则1、C+不允许用户自己定义新的运算符,即只能对已有的C+运算符进行重载。2、C+允许重载的运算符 见P125 表4.1 不能重载的运算符只有5个: . 成员访问运算符 .* 成员指针访问运算符 : 域运算符 sizeof 长度运算符 ?: 条件运算符,18,3、重载运算符不能改变运算对象(即操作数)的个数。4、重载不能改变运算符的优先级别。5、重载不能改变运算符的结合性。6、重载运算符的函数不能有默认的参数。7、重载的运算符必须和用户定义的自定义的类型的对

9、象一起使用,其参数至少应用一个是类对象(或类对象的引用)。8、运算符“=”和“&”用于类对象时,不需要重载。因为系统已经进行了重载。,19,9、重载运算符的功能应类似于该运算符作用于标准类型数据时所实现的功能。10、运算符重载函数可能是类的成员函数(例4.2),也可以是类的友元函数,还可以是既非类的成员函数也不是友元函数的普通函数。(此种方式一般根本不会采用)4.4 运算符重载函数作为类成员函数和 友元函数 例4.2 程序中对运算符“+”进行了重载,并且重载函数operator+是作为Complex类中的成员函数的。 由于重载函数是Complex类中的成员,20,函数,有一个参数是隐含的,运算

10、符函数是用this指针隐式地访问类对象的成员。如:real+c2.real就是 This-real +c2.real 将运算符重载为成员函数后,如出现含该运算符的表达式,如:c1+c2,编译系统把它解释为:c1.oporator+(c2) 即通过对象c1调用运算符重载函数,并以表达式中第二个参数(c2)作为函数实参。,c1.real,21,例4.3 将运算符“+”重载为Complex类的友元函数。#include class Complexpublic: Complex( ) real=0 ; imag=0; Complex(double r,double i) real=r ; imag=i

11、; friend Complex operator+ (Complex ,22,Complex operator+ (Complex ,23,int main( ) Complex c1(3,4), c2(5,-10), c3; c3=c1+c2; coutc1=; c1.display( ); coutc2=; c2.display( ); coutc1+c2=; c3.display( ); return 0;此例与上例比较后区别如下:(1)运算符重载函数是作为Complex的友元函数,24,(2)运算符重载函数有两个参数。即c1+c2 解释为:operator+ (c1,c2) C+规定

12、,有的运算符,如:赋值运算符、下标运算符、函数调用运算符必须定义为类的成员函数;有的运算符只能定义为友元函数,如:流插入()运算符、类型转换运算符。 一般:将单目运算符重载为成员函数,将双目运算符重载为友元函数。 说明:VC6.0它提供的不带后缀.h的头文件不支持把成员函数重载为友元函数。故头文件采用#include ,25,4.5 重载双目运算符双目运算符又称二元运算符,是C+中最常用的运算符。双目运算符有两个操作数,通常在运算符的左右两侧,如3+5,a”,用于两个字符串的等于、小于和大于的比较运算。,26,(1)先建立一个String类:见C4-4-1(VC+).CPP#include u

13、sing namespace std;Class String /String 是用户自己指定的类名public: String( ) p=NULL; /默认构造函数 String( char *str ); /构造函数 void display( ); private: char *p; /字符型指针,用于指向字符串 ;,27,String:String( char *str ) /定义构造函数 p=str; /使p指向实参字符串void String:display( ) coutp; /输出p所指向的字符串int main( ) String string1(Hello),string2

14、(Book); string1.display(); coutendl; /换行 string2.display(); coutendl; return 0;,28,(2)增加“”运算符重载部分。C4-4-2(VC).CPP#include #include class String public: String( )p=NULL; String(char *str); /重载构造函数声明 friend bool operator(String ,29,String:String (char *str) p=str; void String:display( ) cout (String ,3

15、0,(3)扩展到对3个运算符重载。 C4-4-3(VC).CPP#include #include class Stringpublic: String( )p=NULL; String(char *str); friend bool operator(String ,31,String:String (char *str) p=str; void String:display( ) cout (String ,32,bool operator= (String ,33,(4) 进一步完善成最终的程序。 C4-4-4(VC).CPP#include #include class Stringp

16、ublic: String( )p=NULL; String(char *str); friend bool operator(String ,34,String:String (char *str) p=str; void String:display( ) cout (String ,35,bool operator= (String ,36,int main( )String string1(Hello), string2(Book), string3(Computer), string4(Hello); compare(string1,string2); compare(string2

17、,string3); compare(string1,string4); return 0;,37,本程序设计的指导思想:先搭框架,逐步扩充,由简到繁,最后完善。边编程,边调试,边扩充。4.6 重载单目运算符 单目运算符只有一个参数,如-b,!a,*p,+i,i+等。重载单目运算符与重载双目运算符的方法是一样的,但由于单目运算符只有一个操作数,因此运算符重载函数只有一个参数,如果运算符重载函数作为成员函数,则还可省略此参数。 下面的例以自增运算符“+”进行重载。,38,例 4.5 “+”前缀运算符的重载。#include using namespace std;class Time publi

18、c: Time( )minute=0;sec=0; /默认构造函数 Time(int m,int s):minute(m),sec(s) /构造函数重载 Time operator+( ); /声明运算符重载函数 void display ( )coutminute:secendl; /定义输出时间函数 private: int minute; int sec; ;,39,Time Time:operator+( ) /定义运算符+重载函数 if(+sec=60) sec-=60; /满60秒进1分钟 +minute; return *this; /返回当前对象值 int main( ) Ti

19、me time1(34,0); for (int i=0;i61;i+) +time1; time1.display( ); return 0;,40,此例是前置自增运算符,那后置自增运算符怎么重载呢? C+约定:如果在自增(自减)运算符重载函数中,增加一个int型参数,就是后置自增(自减)运算符。例4.6 含后置的自增运算符。#include using namespace std;class Time public:,41,Time( ) minute=0;sec=0; Time(int m,int s):minute(m),sec(s) Time operator+( ); /声明前置自

20、增运算符“+”重载函数 Time operator+(int); /声明后置自增运算符“+”重载函数 void display()coutminute :secendl; private: int minute; int sec; ;,42,Time Time:operator+( ) /定义前置自增运算符“+”重载函数 if(+sec=60) sec-=60; +minute; return *this; /返回自加后的当前对象Time Time:operator+( int ) /定义后置自增运算符“+”重载函数 Time temp(*this); sec+; if(sec=60) sec

21、-=60; +minute; return temp; /返回的是自加前的对象,43,int main( )Time time1(34,59), time2; cout time1 : ; time1.display( ); +time1; cout+time1: ; time1.display( ); time2=time1+; /将自加前的对象的值赋给time2 couttime1+: ; time1.display( ); cout time2 : ; time2.display( ); /输出time2对象的值 return 0;,44,说明:重载后置自增运算符时,多了一个int型的参

22、数,增加这个参数的目的只是为了与前置自增运算符重载函数相区别,没有任何作用,因此在定义函数时只给出了类型名而没有参数名。4.7 重载流插入运算符和流提取运算符 C+流插入运算符“”是C+在类库中提供的,所有的C+编译系统都在类库中提供输入流类istream和输出流类ostream。cin和cout分别是istream类和ostream类的对象。在类库提供的头文件中已经对“”进行了重,45,载,使之作为流插入运算符和流提取运算符,能用来输出和输入C+标准类型的数据。这就是前面每一个程序都加: #include 语句的原因,即把头文件包含到本程序中来。 用户自己定义的类型的数据,是不能直接用“”来

23、输出和输入的。如果想让它们输出和输入自己声明的类型的数据,必须对它们重载。 对“”重载的函数形式如下:,46,istream 即 :重载运算符“”的函数的第一个参数和函数的类型都必须是istream&类型,第二个参数是要进行输入操作的类。 重载运算符“”和“”的函数作为友元函数或普通的函数(一般很少使用),而不能将它们定义为成员函数。原因是什么?(第一个参数的类型不是自定义的类类型),47,4.7.1 重载流插入运算符“ class Complex public: Complex()real=0;imag=0; Complex(double r,double i)real=r;imag=i;

24、Complex operator + (Complex ,/运算符“+”重载为成员函数,48,Complex Complex:operator + (Complex ,49,说明:编译系统在主程序中的coutc3;解释为:operator (cout,c3)即以cout和c3作为实参,调用operator 函数:ostream,此行中的是C+预定义的流插入符,50,4.7.2 重载流提取运算符“” 重载流提取运算符“”两种运算符。 用“cin”输入复数, 用“cout”来输出复数,51,#include class Complex public: friend ostream,52,ostre

25、am ,53,int main( ) Complex c1,c2; cinc1c2; coutc1=c1endl; coutc2=c2endl; return 0; 有了运算符重载,在声明了类之后,我们就可以像使用标准类型一样来使用自己声明的类了。,54,4.8 不同类型数据间的转换 4.8.1 标准类型数据间的转换1.隐式转换。如:int i=6; i=7.5+i; 赋值后,i的值为132. 显式转换 C+中的形式: 类型名(数据) 如:int(89.5) C语言中的形式 (类型名)数据 如:(int)89.5问题:以上是标准类型的转换,那么:一个自定义类的对象能否转换成标准类型的数据呢?,

26、55,4.8.2 转换构造函数 转换构造函数的作用是将一个其他类型的数据转换成一个指定的类的对象。回顾构造函数:以Complex类为例(1)默认构造函数。 Complex( ); /没有参数(2)用于初始化的构造函数。 Complex( double r , double I ); /两个以上的参数(3)用于复制对象的拷贝构造函数。 Complex ( Complex /形参是本类对象的引用,56,(4) 转换构造函数。Complex(double r) real=r ; imag=0; 转换构造函数只有一个参数,其作用是将double型的参数r转换成Complex类的对象。 以上几种构造函数

27、可以同时出现在一个类中,它们是构造函数的重载。编译系统会根据建立对象时给出的实参的个数与类型去选择形参与之匹配的构造函数。补充例:转换构造函数的使用。 见C4-3-3.cpp或C4-3-4.cpp由C4-3修改而来。,57,#include class Complex public: Complex( ) real=0;imag=0; /默认构造函数(没有参数) Complex(double r) real=r ; imag=0; /转换构造函数,将实数转换为复数 Complex(double r,double i)real=r;imag=i; /构造函数重载(有两个参数) friend Co

28、mplex operator+ (Complex c1, Complex c2); /声明友元的重载运算符+的函数 void display( ); /普通成员函数,用于输出数据,58,rivate: double real; double imag; ;Complex operator+ (Complex c1,Complex c2) /定义重载运算符+的函数 return Complex(c1.real+c2.real, c1.imag+c2.imag); void Complex:display( ) cout(real,imagi)endl; ,59,int main( ) Compl

29、ex c1(3,4) , c2(5,-10) ,c3,c4,c5,c6; c3=c1+c2; /运算符+用于复数运算 coutc1=; c1.display( ); coutc2=; c2.display( ); coutc3=c1+c2=; c3.display( );,60,c3=Complex(1.0)+c3; /通过显式调用Complex(1.0) /将实数1.0转换成复数,然后就可以实现相加了 c4=1.0+c1; /隐式调用转换构造函数Complex(double r) c5=c2+Complex(1.0); c6=2.0+c2; cout1+c3=; c3.display();

30、cout1+c1=; c4.display(); coutc2+1=; c5.display(); cout2.0+c2=; c6.display(); return 0;,61,总结: 使用转换构造函数的方法。(1)先声明一个类(如上面的Complex)(2)在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的类型,在函数体中指定转换的方法。(3)在该类的作用域内可以用以下形式进行类型转换: 类名(指定类型的数据) 就可以将指定类型的数据转换为此类的对象 与前述基本数据类型: 类型名(数据) 的转换格式非常类似,62,4.8.3 类型转换函数 用转换构造函数可以将一个指定类型的数

31、据转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据,如:将一个Complex类对象转换成double类型的数据。 C+提供类型转换函数来实现上述问题。类型转换函数的作用是将一个类的对象转换成另一个类型的数据。 先看例题,然后再来看实现格式。 例4.9 类型转换函数的使用。,63,#include using namespace std;class Complex public: Complex( ) real=0 ; imag=0; Complex(double r,double i) real=r;imag=i; operator double( ) return rea

32、l; /类型转换函数 private: double real; double imag; ;,64,int main( ) Complex c1(3,4) , c2(5,-10) , c3; double d, e; d=2.5+c1; /要求将一个double数据与Complex类数据相加 /因为d是一个实型数据,故要先将c1转换成实型数据, /然后才能相加,再赋值给d coutdendl; e=3-c2; couteendl; return 0;,运行结果为:5.5 -2,65,类型转换函数的一般形式为:operator 类型名( ) 实现转换的语句如: operator double(

33、 ) return real; 函数返回double型变量real的值。它有作用是将一个Complex类对象转换为一个double型数据,其值是Complex类中的数据成员real的值。其中的函数名是: operator double 在函数名前不能指定函数类型,函数没有参数,其返回值是由函数名中指定的类型名来确定的。,66,类型转换函数只能作为成员函数,因为转换的主体是本类的对象,不能作为友元函数或普通函数。 例4.10 (1)此例只包含“转换构造函数”和“运算符重载函数”。 (与上面的补充例C4-3-3.cpp相似) 见C4-10-1.CPP,67,#include class Compl

34、ex public: Complex( ) real=0;imag=0; Complex(double r) real=r;imag=0; /转换构造函数:将实数转换成复数 Complex(double r,double i)real=r;imag=i; friend Complex operator + (Complex c1,Complex c2); /重载运算符“+”的友元函数 void display(); private: double real; double imag; ;,68,Complex operator + (Complex c1,Complex c2) /定义运算符“

35、+”重载函数 return Complex(c1.real+c2.real, c1.imag+c2.imag); void Complex:display() cout(real+imagi)endl;int main( ) Complex c1(3,4),c2(5,-10),c3; /c3=c1+Complex(2.5); /显式调用转换构造函数 c3=c1+2.5; /复数与double数据相加,结果要为复数。 /也可c3=2.5+c1; 隐式调用。先将2.5转换成复数,然后两复数相加 c3.display( ); return 0;,69,说明: 在已定义了相应的转换构造函数情况下,将运

36、算符“+”函数重载为友元函数,在进行两个复数相加时,可以用交换律。如果将运算符“+”函数重载为类的成员函数,则不能用交换律。 基于以上原因,一般情况下将双目运算符函重载为友元函数,单目运算符则多重载为成员函数。,70,(2)此例包含转换构造函数、运算符重载函数和类型转换函数。 见C4-10-2.CPP#include class Complex public: Complex()real=0;imag=0; /默认构造函数 Complex(double r)real=r;imag=0; /转换构造函数 Complex(double r,double i) real=r;imag=i; /构造函

37、数重载,71,ublic: operator double( ) return real; /类型转换函数 friend Complex operator + (Complex c1, Complex c2); /重载运算符“+” void display( );private: double real; double imag; ;,72,Complex operator + (Complex c1,Complex c2) return Complex(c1.real+c2.real, c1.imag+c2.imag); void Complex:display( ) cout(real,i

38、magi)endl;int main( ) Complex c1(3,4),c2(5,-10),c3; c3=c1+2.5; c3.display( ); return 0; ,73,说明:程序在处理c3=c1+2.5;时出现二义性,即编译通不过。原因: 一种理解为:调用转换构造函数,把2.5变成Complex类对象,然后调用运算符“+”重载函数,与c1进行复数相加; 另一种理解为:调用类型转换函数,把c1转换为double型数,然后与2.5进行相加。 由于上面两种理解都正确,故系统无法判定,出现二义性。如果要使用类型转换函数,就应当删去运算符“+”重载函数(结果变为:(5.5,0i) ,与实际要求有些不符)。,74,练习:转换构造函数的应用(见P144.CPP)阅读程序,写出程序运行结果#includeclass AA int x;public:AA( int a=0 ) x=a ; void display( ) coutxendl ; operator int( ) return x; ;,75,AA Max( AA a , AA b )if(ab) return a;return b;void main( )AA a(33) , b(55) , c ;c= Max( a , b );c.display( );,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号