




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第10章章 运算符重载运算符重载10.1 什么是运算符重载什么是运算符重载10.2 运算符重载的方法运算符重载的方法10.3 重载运算符的规则重载运算符的规则10.4 运算符重载函数作为类成员函数和友元函数运算符重载函数作为类成员函数和友元函数10.5 重载双目运算符重载双目运算符10.6 重载单目运算符重载单目运算符10.7 重载流插入运算符和流提取运算符重载流插入运算符和流提取运算符10.8 不同类型数据间的转换不同类型数据间的转换 10.1 什么是运算符重载什么是运算符重载lC+中预定义的运算符的操作对象只能是基中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定本
2、数据类型。但实际上,对于许多用户自定义的类型,也需要类似的运算。这时就必须义的类型,也需要类似的运算。这时就必须重新定义这些运算符,赋于已有运算符新的重新定义这些运算符,赋于已有运算符新的功能,使之能够用于特定类型执行特定操作。功能,使之能够用于特定类型执行特定操作。l实际上,很多实际上,很多C+操作符已经被重载。例如,操作符已经被重载。例如,将将*操作符用于地址,将得到在这个地址中的操作符用于地址,将得到在这个地址中的值;但将它用于两个数字时,得到的将是它值;但将它用于两个数字时,得到的将是它们的乘积。们的乘积。lC+根据操作数的数目和类型来决定采用哪根据操作数的数目和类型来决定采用哪种操作
3、。种操作。l使同一个运算符作用于不同类型的数据时导使同一个运算符作用于不同类型的数据时导致不同的行为的这种机制称为致不同的行为的这种机制称为。lC+通过重载运算符使之用于通过重载运算符使之用于,扩展了运算符的功能,这也是扩展了运算符的功能,这也是C+最具吸引最具吸引力的优点之一。力的优点之一。运算符重载机制运算符重载机制l运算符重载是通过重载一种特殊函数运算符重载是通过重载一种特殊函数运算符函数运算符函数来实现的。来实现的。l对对C+运算符可作如下理解:运算符可作如下理解:l编译器在对运算符进行编译处理时,将一个运算符编译器在对运算符进行编译处理时,将一个运算符编译成如下形式:编译成如下形式:
4、l一元运算符:一元运算符:obj operator(obj)l二元运算符:二元运算符:obj1obj2 operator(obj1,obj2)l由于由于C+中有前增(减)、后增(减),为了区分中有前增(减)、后增(减),为了区分它们,它们,C+将后增(减)编译成:将后增(减)编译成:l后增:后增:obj+ operator+(obj,0)l后减:后减:obj- operator-(obj,0)l依照上述规则,依照上述规则,8+9、10.5+3.5分别编译成运分别编译成运算符函数调用形式为:算符函数调用形式为:loperator+(8,9);loperator+(10.5,3.5);lC+为为+
5、运算符提供了多种运算符函数,其原运算符提供了多种运算符函数,其原型有:型有:loperator+(int,int);loperator+(double,double);l等等10.2 运算符重载的方法运算符重载的方法l运算符重载的方法是定义一个重载运算符的运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的。就是说,运算符重载是通过定义函数实现的。l重载运算符的函数一般格式如下:重载运算符的函数一般格式如下: l函数类型
6、函数类型 operator 运算符名称运算符名称 (形参表列形参表列)l l 对运算符的重载处理对运算符的重载处理 l#include using namespace std;class Complex double real; double imag;public: Complex( ) real=0; imag=0; Complex(double r,double i):real(r),imag(i) Complex operator+(Complex &c1,Complex &c2); void display( );Complex operator+(Complex &c1,Compl
7、ex &c2) Complex c; c.real=c1.real+c2.real; c.imag=c1.imag+c2.imag; return c;void Complex:display( ) cout(real,imagi)endl;int main( ) Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; coutc1=; c1.display( ); coutc2=; c2.display( ); cout、=运算符,运算符重运算符,运算符重载函数载函数必须必须为类的成员函数。为类的成员函数。10.5 重载双目运算符重载双目运算符l双目运算符双目运算符(
8、或称二元运算符或称二元运算符)是是C+中最常用中最常用的运算符。双目运算符有两个操作数,通常的运算符。双目运算符有两个操作数,通常在运算符的左右两侧,如在运算符的左右两侧,如3+5,a=b,i10等。等。在重载双目运算符时,不言而喻在函数中应在重载双目运算符时,不言而喻在函数中应该有两个参数。下面再举一个例子说明重载该有两个参数。下面再举一个例子说明重载双目运算符的应用。双目运算符的应用。例例l定义一个字符串类定义一个字符串类String,用来存放不定长,用来存放不定长的字符串,重载运算符的字符串,重载运算符“=”,“”,用,用于两个字符串的等于、小于和大于的比较运于两个字符串的等于、小于和大
9、于的比较运算。算。l下面分几步来介绍编程过程。下面分几步来介绍编程过程。 先建立一个先建立一个String类类l#include lusing namespace std;lclass Stringllpublic:l String( )l l p=NULL; /默认构造函数默认构造函数l l String(char *str); /构造函数构造函数l void display( );lprivate:l char *p; /字符型指针,用于指向字符串字符型指针,用于指向字符串l;lString:String(char *str) /定义构造函数定义构造函数ll p=str; /使使p指向实参
10、字符串指向实参字符串llvoid String:display( ) /输出输出p所指向的字符串所指向的字符串ll coutp;llint main( )ll String string1(Hello),string2(Book);l string1.display( );l cout”。l#include l#include lusing namespace std;lclass Stringllpublic:l String( )l l p=NULL; /默认构造函数默认构造函数l l String(char *str); /构造函数构造函数l void display( );l frie
11、nd bool operator(String &string1,String &string2);lprivate:l char *p; /字符型指针,用于指向字符串字符型指针,用于指向字符串l;lString:String(char *str) /定义构造函数定义构造函数ll p=str; /使使p指向实参字符串指向实参字符串llvoid String:display( ) /输出输出p所指向的字符串所指向的字符串ll cout(String &string1,String &string2)ll if(strcmp(string1.p,string2.p)0)l return true;
12、l else return false;llint main( )ll String string1(Hello),string2(Book);l coutstring2)endl;ll程序运行结果为程序运行结果为1。l其他两个运算符的重载如法炮制即可。其他两个运算符的重载如法炮制即可。 扩展到对扩展到对3个运算符重载。个运算符重载。l见教材见教材P325l通过这个例子,不仅可以学习到有关双目运算符重通过这个例子,不仅可以学习到有关双目运算符重载的知识,而且还可以学习怎样去编写载的知识,而且还可以学习怎样去编写C+程序。程序。l这种方法的指导思想是:这种方法的指导思想是: 先搭框架,逐步扩充,
13、由先搭框架,逐步扩充,由简到繁,最后完善。简到繁,最后完善。l边编程,边调试,边扩充。千万不要企图在一开始边编程,边调试,边扩充。千万不要企图在一开始时就解决所有的细节。类是可扩充的,可以一步一时就解决所有的细节。类是可扩充的,可以一步一步地扩充它的功能。最好直接在计算机上写程序,步地扩充它的功能。最好直接在计算机上写程序,每一步都要上机调试,调试通过了前面一步再做下每一步都要上机调试,调试通过了前面一步再做下一步,步步为营。一步,步步为营。10.6 重载单目运算符重载单目运算符l单目运算符只有一个操作数,如单目运算符只有一个操作数,如!a,-b,&c,*p,还有最常用的,还有最常用的+i和和
14、-i等。重载单目运算等。重载单目运算符的方法与重载双目运算符的方法是类似的。符的方法与重载双目运算符的方法是类似的。但由于单目运算符只有一个操作数,因此运但由于单目运算符只有一个操作数,因此运算符重载函数只有一个参数。算符重载函数只有一个参数。l单目运算符一般重载为成员函数。单目运算符一般重载为成员函数。例例l有一个有一个Time类,包含数据成员类,包含数据成员minute(分分)和和sec(秒秒),模拟秒表,每次走一秒,满,模拟秒表,每次走一秒,满60秒进秒进一分钟,此时秒又从一分钟,此时秒又从0开始算。要求输出分和开始算。要求输出分和秒的值。秒的值。l#include lusing nam
15、espace std;lclass Timellpublic:l Time( )l l minute=0; /默认构造函数默认构造函数l sec=0;l l Time(int m,int s):minute(m),sec(s) /构造函数重载构造函数重载l Time operator+( ); /声明运算符重载函数声明运算符重载函数l void display( )l l coutminute:sec=60)l l sec-=60; /满满60秒进秒进1分钟分钟l +minute;l l return *this; /返回当前对象值返回当前对象值llint main( )ll Time tim
16、e1(34,0);l for (int i=0; i61; i+)l l +time1;l time1.display( );l l return 0;ll“+”和和“-”运算符有两种使用方式,前置自运算符有两种使用方式,前置自增运算符和后置自增运算符,它们的作用是增运算符和后置自增运算符,它们的作用是不一样的,在重载时怎样区别这二者呢?不一样的,在重载时怎样区别这二者呢?l针对针对“+”和和“-”这一特点,这一特点,C+约定:约定: 在在自增自增(自减自减)运算符重载函数中,增加一个运算符重载函数中,增加一个int型形参,就是后置自增型形参,就是后置自增(自减自减)运算符函数。运算符函数。例
17、例l在上例程序的基础上增加对后置自增运算符在上例程序的基础上增加对后置自增运算符的重载。修改后的程序如下:的重载。修改后的程序如下:lclass Timellpublic:l Time( )l l minute=0; /默认构造函数默认构造函数l sec=0;l l Time(int m,int s):minute(m),sec(s) /构造函数重载构造函数重载l Time operator+( ); /声明前置自增运算符声明前置自增运算符+重载函数重载函数l Time operator+(int); /声明后置自增运算符声明后置自增运算符+重载函数重载函数l void display( )l
18、 l coutminute:sec=60)l l sec-=60;l +minute;l l return *this;llTime Time:operator+(int)ll Time temp(*this);l sec+;l if(sec=60)l l sec-=60;l +minute;l l return temp; /返回的是自加前的对象返回的是自加前的对象llint main( )ll Time time1(34,59),time2;l couttime1 : ;l time1.display( );l +time1;l cout+time1: ;l time1.display(
19、);l time2=time1+; l couttime1+: ;l time1.display( );l couttime2 :;l time2.display( );10.7 重载流插入运算符和流提取运算符重载流插入运算符和流提取运算符lC+的流插入运算符的流插入运算符“”是是C+在类库中提供的,所有在类库中提供的,所有C+编译系统都在类库编译系统都在类库中提供输入流类中提供输入流类istream和输出流类和输出流类ostream。lcin和和cout分别是分别是istream类和类和ostream类的对象。类的对象。在类库提供的头文件中已经对在类库提供的头文件中已经对“”进行了进行了重载
20、,使之作为流插入运算符和流提取运算符,能重载,使之作为流插入运算符和流提取运算符,能用来输出和输入用来输出和输入C+标准类型标准类型的数据。因此,凡是的数据。因此,凡是用用“cout”对标准类型数据进行输入对标准类型数据进行输入输出的,都要用输出的,都要用#include 把头文件包把头文件包含到本程序文件中。含到本程序文件中。l用户自己定义类型用户自己定义类型的数据,是不能直接用的数据,是不能直接用“”来输出和输入的。如果想用它们输出和输入来输出和输入的。如果想用它们输出和输入自己声明的类型的数据,必须对它们重载。自己声明的类型的数据,必须对它们重载。l对对“”重载的函数形式如下:重载的函数
21、形式如下: listream& operator (istream &,自定义类自定义类 &);lostream& operator ”的函数的第一个参数和函数的类的函数的第一个参数和函数的类型都型都必须必须是是istream&类型,第二个参数是要进行输类型,第二个参数是要进行输入操作的类。重载入操作的类。重载“”和和“”的函数作为友元函数或普通的函数,而不能的函数作为友元函数或普通的函数,而不能将它们定义为成员函数。将它们定义为成员函数。10.7.1 重载流插入运算符重载流插入运算符“”l例例 用重载的用重载的“”输出复数。输出复数。lclass Complexllpublic:l Comp
22、lex( )l l real=0;l imag=0;l l Complex(double r,double i)l l real=r;l imag=i;l l Complex operator + (Complex &c2);l friend ostream& operator (ostream&,Complex&);lprivate:l double real;l double imag;l;lComplex Complex:operator + (Complex &c2)ll return Complex(real+c2.real,imag+c2.imag);llostream& oper
23、ator (ostream& output,Complex& c)ll output(c.real+c.imagi)endl;l return output;lint main( ) Complex c1(2,4),c2(6,10),c3; c3=c1+c2; cout”lC+预定义的运算符预定义的运算符“”的作用是从一个输的作用是从一个输入流中提取数据,如入流中提取数据,如“cini;”表示从输入流表示从输入流中提取一个整数赋给变量中提取一个整数赋给变量i(假设已定义假设已定义i为为int型型)。重载流提取运算符的目的是希望将。重载流提取运算符的目的是希望将“”用于输入自定义类型的对象的信息
24、。用于输入自定义类型的对象的信息。lclass Complexllpublic:l Complex( )l l real=0;l imag=0;l l Complex(double r,double i)l l real=r;l imag=i;l l Complex operator + (Complex &c2);l friend ostream& operator (istream&,Complex&);lprivate:l double real;l double imag;l;lComplex Complex:operator + (Complex &c2)ll return Comp
25、lex(real+c2.real,imag+c2.imag);llostream& operator (ostream& output,Complex& c)ll output(c.real+c.imagi) (istream& input,Complex& c) coutc.real; coutc.imag; return input;lint main( )ll Complex c1,c2;l cinc1c2;l coutc1=c1endl;l coutc2=c2endl;l return 0;l10.8 不同类型数据间的转换不同类型数据间的转换10.8.1 标准类型数据间的转换标准类型数
26、据间的转换l在在C+中,某些不同类型数据之间可以自动转换,中,某些不同类型数据之间可以自动转换,例如例如lint i = 6;li = 7.5 + i;l编译系统对编译系统对 7.5是作为是作为double型数处理的,在求解型数处理的,在求解表达式时,先将表达式时,先将6转换成转换成double型,然后与型,然后与7.5相加,相加,得到和为得到和为13.5,在向整型变量,在向整型变量i赋值时,将赋值时,将13.5转换转换为整数为整数13,然后赋给,然后赋给i。这种转换是由。这种转换是由C+编译系统编译系统自动完成的,用户不需干预。这种转换称为隐式类自动完成的,用户不需干预。这种转换称为隐式类型
27、转换。型转换。lC+还提供显式类型转换,程序人员在程序中指定还提供显式类型转换,程序人员在程序中指定将一种指定的数据转换成另一指定的类型,其形式将一种指定的数据转换成另一指定的类型,其形式为为 l类型名类型名(数据数据) l如如lint(89.5) l其作用是将其作用是将89.5转换为整型数转换为整型数89。l对于用户自己声明的类型,编译系统并不知道怎样对于用户自己声明的类型,编译系统并不知道怎样进行转换。进行转换。解决这个问题的关键是让编译系统知道解决这个问题的关键是让编译系统知道怎样去进行这些转换,需要定义专门的函数来处理。怎样去进行这些转换,需要定义专门的函数来处理。10.8.2 转换构
28、造函数转换构造函数的作用是将一个其他类型的数据转换成一个类的作用是将一个其他类型的数据转换成一个类的对象。的对象。l先回顾一下以前学习过的几种构造函数:先回顾一下以前学习过的几种构造函数: l默认构造函数。以默认构造函数。以Complex类为例,函数原型的形式为类为例,函数原型的形式为 Complex( ); /没有参数没有参数l用于初始化的构造函数。函数原型的形式为用于初始化的构造函数。函数原型的形式为 Complex(double r,double i); /形参表列中一般有两个形参表列中一般有两个以上参数以上参数l用于复制对象的复制构造函数。函数原型的形式为用于复制对象的复制构造函数。函
29、数原型的形式为 Complex (Complex &c); /形参是本类对象的引用形参是本类对象的引用l现在又要介绍一种新的构造函数现在又要介绍一种新的构造函数转换构转换构造函数。造函数。l转换构造函数只有一个形参,如转换构造函数只有一个形参,如 lComplex(double r) real=r;imag=0;l其作用是将其作用是将double型的参数型的参数r转换成转换成Complex类的对象,将类的对象,将r作为复数的实部,虚作为复数的实部,虚部为部为0。用户可以根据需要定义转换构造函数,用户可以根据需要定义转换构造函数,在函数体中告诉编译系统怎样去进行转换。在函数体中告诉编译系统怎样去
30、进行转换。l在类体中,可以有转换构造函数,也可以没在类体中,可以有转换构造函数,也可以没有转换构造函数,视需要而定。以上几种构有转换构造函数,视需要而定。以上几种构造函数可以同时出现在同一个类中,它们是造函数可以同时出现在同一个类中,它们是构造函数的重载。编译系统会根据建立对象构造函数的重载。编译系统会根据建立对象时给出的实参的个数与类型选择形参与之匹时给出的实参的个数与类型选择形参与之匹配的构造函数。配的构造函数。l使用转换构造函数将一个指定的数据转换为类对象使用转换构造函数将一个指定的数据转换为类对象的方法如下:的方法如下: l(1) 先声明一个类。先声明一个类。l(2) 在这个类中定义一
31、个只有一个参数的构造函在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的类型,在函数体中指数,参数的类型是需要转换的类型,在函数体中指定转换的方法。定转换的方法。l(3) 在该类的作用域内可以用以下形式进行类型在该类的作用域内可以用以下形式进行类型转换:转换: 类名类名(指定类型的数据指定类型的数据)l就可以将指定类型的数据转换为此类的对象。就可以将指定类型的数据转换为此类的对象。class Complexpublic: Complex( ):real(0),imag(0) Complex(double r,double i):real(r),imag(i) Complex(do
32、uble r):real(r),imag(0) Complex operator + (Complex c2); friend ostream& operator (ostream&,Complex&);private: double real; double imag;Complex Complex:operator + (Complex c2) return Complex(real+c2.real,imag+c2.imag);ostream& operator (ostream& output,Complex& c) output(c.real+c.imagi)endl; return
33、output;lint main( )ll Complex c1(3,6),c2;l c2=c1+(Complex)8.2; l /c2=c1+Comples(8.2);l /c2=c1+8;l /c2=8+c1; l coutc2endl;l return 0;llclass Complexllpublic:l Complex( ):real(0),imag(0)l Complex(double r,double i):real(r),imag(i)l Complex(double r):real(r),imag(0);l friend Complex operator + (Complex
34、 c1,Complex c2);l friend ostream& operator (ostream&,Complex&);lprivate:l double real;l double imag;l;lComplex operator + (Complex c1,Complex c2)ll return Complex(c1.real+c2.real,c1.imag+c2.imag);llostream& operator (ostream& output,Complex& c)ll output(c.real+c.imagi)endl;l return output;llint main
35、( )ll Complex c1(3,6),c2;l c2=8+c1; /okl coutc2endl;l return 0;l10.8.3 类型转换函数类型转换函数l用转换构造函数可以将一个指定类型的数据用转换构造函数可以将一个指定类型的数据转换为类的对象。但是不能反过来将一个类转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据的对象转换为一个其他类型的数据(例如将一例如将一个个Complex类对象转换成类对象转换成double类型数据类型数据)。lC+提供类型转换函数提供类型转换函数(type conversion function)来解决这个问题。类型转换函数的作用是将
36、一个类来解决这个问题。类型转换函数的作用是将一个类的对象转换成另一类型的数据。的对象转换成另一类型的数据。l类型转换函数的一般形式为类型转换函数的一般形式为 loperator 类型名类型名( )ll 实现转换的语句实现转换的语句ll在函数名前面在函数名前面不能指定函数类型不能指定函数类型,函数,函数没有参数没有参数。其返回值的类型是由其返回值的类型是由函数名函数名中指定的类型名来确定中指定的类型名来确定的。类型转换函数的。类型转换函数只能作为成员函数只能作为成员函数,因为转换的,因为转换的主体是本类的对象。主体是本类的对象。l如果已声明了一个如果已声明了一个Complex类,可以在类,可以在
37、Complex类类中这样定义类型转换函数:中这样定义类型转换函数: operator double( ) return real; ldouble类型经过重载后,除了原有的含义外,还获类型经过重载后,除了原有的含义外,还获得新的含义得新的含义(将一个将一个Complex类对象转换为类对象转换为double类型数据,并指定了转换方法类型数据,并指定了转换方法)。这样,编译系统不。这样,编译系统不仅能识别原有的仅能识别原有的double型数据,而且还会把型数据,而且还会把Complex类对象作为类对象作为double型数据处理。型数据处理。l那么程序中的那么程序中的Complex类对具有双重身份,类对具有双重身份,既是既是Complex类对象,又可作为类对象,又可作为double类型类型数据。数据。Complex类对象只有在需要时才进行类对象只有在需要时才进行转换,要根据表达式的上下文来决定。转换,要根据表达式的上下文来决定。l转换构造函数和类型转换运算符有一个共同转换构造函数和类型转换运算符有一个共同的功能:的功能: 当需要的时候,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- ceo聘任合同标准文本
- 与舞蹈学校合同标准文本
- mpp管采购合同样本
- 公园物业出租合同标准文本
- 会务公司赞助合同样本
- 供水排水设施建设运营合同
- 公司车辆转让协议合同标准文本
- 公司礼盒采购合同样本
- 二手车按揭合同样本
- 公路监理延期合同标准文本
- 在线网课知慧《贵州省情(贵州理工学院)》单元测试考核答案
- MOOC 概率统计-西南石油大学 中国大学慕课答案
- 2022年四川省南充市【中考】语文真题【带答案】
- 2024年低压开关柜市场前景分析:我国低压开关柜市场规模约为28亿元
- 2024浙江省烟草专卖局(公司)管理类岗位招聘笔试参考题库附带答案详解
- 辽宁省沈阳市2023-2024学年高一上学期期末质量监测英语试题(含答案)
- 核磁移机方案
- 第5课《黄河颂》课件-2023-2024学年统编版语文七年级下册
- 酒店升级改造方案
- 教师培训绩效评价报告
- 淡季服装促销活动方案
评论
0/150
提交评论