您好,欢迎访问三七文档
1运算符重载第7章运算符重载2运算符重载7.1运算符重载概述1、系统为基本数据类型提供了大量运算符。如:intx,y;x=x+y;表达简洁,使用方便。2、问题的提出:定义复数类。问题的引入:3运算符重载定义一个简化的复数类complex:classcomplex{public:doublereal,imag;complex(doubler=0,doublei=0){real=r;imag=i;}};若要把类complex的两个对象com1和com2加在一起,下面的语句是不能实现的:main(){complexcom1(1.1,2.2),com2(3.3,4.4),total;total=com1+com2;//错误//…return0;}4运算符重载错误的原因:complex类类型不是预定义的基本数据类型,而是用户自定义的数据类型。C++知道如何相加两个int型数据,或相加两个float型数据。但是C++还无法直接将两个complex类对象相加。为了表达上的方便,人们希望能预定义的运算符在特定类的对象上也能使用,如希望能够实现total=com1+com2;这就需要重载运算符“+”来解决。这一章就学习如何将运算符作用于自定义类型的对象上:即运算符重载5运算符重载运算符重载的概念通过定义多个同名函数可以实现函数的重载。在C++语言中,运算符也被看成一种特殊的函数,也能够被重载。在前面已经接触过很多运算符重载的例子。例如:coutHelloworld!;cout56;在这里,同一个运算符“”,完成了两种不同类型数据的输出,这就是通过对运算符“”重载的结果。6运算符重载在重载某个运算符时,就是定义一个重载运算符的函数,函数名为operator@(@为要重载的运算符)。例如:operator+()operator-()operator*()operator/()operator()运算符重载是通过定义函数实现的,运算符重载实质上是函数的重载(遵循函数重载的原则)。7运算符重载【例7.1】用运算符重载实现复数的加运算:#includeiostream.hclasscomplex{public:doublereal;doubleimag;complex(doubler=0,doublei=0){real=r;imag=i;}};complexoperator+(complexc1,complexc2){complexc;c.real=c1.real+c2.real;c.imag=c1.imag+c2.imag;returnc;}8运算符重载main(){complexcom1(1.1,2.2),com2(3.3,4.4),total1,total2;total1=operator+(com1,com2);coutreal1=total1.realimag1=total1.imagendl;total2=com1+com2;coutreal2=total2.realimag2=total2.imagendl;return0;}换个普通函数名?9运算符重载运算符重载的意义从功能上来讲,通过运算符能实现的功能通过函数一样能够实现。也就是说运算符重载没有在程序的功能上带来好处。运算符重载可以使程序更加简洁,使表达式更加直观,增加可读性。运算符重载的使用也不宜过多,在完成同样功能的情况下,使用运算符比使用明确的函数调用能使程序更清晰,才使用运算符重载。10运算符重载运算符重载规则1.运算符重载不能改变运算符的优先级和结合性。C++语言内部已经规定了所有运算符的优先级。不论运算符作用于什么对象,该优先级都不能改变。也不能通过重载改变一个运算符的结合性。2.运算符重载不能改变运算符的操作数的个数。单目运算符只能包含一个操作数,双目运算符必须有两个操作数,不能试图通过运算符重载改变操作数的个数。3.运算符重载不能使用默认参数。与普通的函数重载不同,运算符重载时,不能使用默认的参数值,必须明确指出每一个操作数。11运算符重载4.运算符重载只能作用于自定义类型。5.不能建立新的运算符。6.不能改变运算符的含义。7.运算符必须显式重载,不能隐式重载例如,重载了运算符+和运算符=后,语句obj3=obj1+obj2;是正确的,但是语句obj1+=obj2;是不正确的。要想使该语句成立,必须显式重载运算符+=。12运算符重载运算符重载函数要求至少有一个参数是类的对象。为了能操作对象的数据成员(一般为私有),在进行重载时主要采用两种方式:成员函数方式和友元函数方式。7.2.1友元运算符函数在C++中,可以把运算符重载函数定义成某个类的友元函数,称为友元运算符函数。7.2运算符重载的两种方式13运算符重载1.友元运算符函数定义的语法形式友元运算符函数的原型在类的内部声明格式如下:classX{//…friend返回类型operator运算符(形参表);//…};在类外定义友元运算符函数的格式如下:返回类型operator运算符(形参表){函数体}14运算符重载2.双目运算符重载双目运算符是有两个操作数的运算符。当用友元函数重载双目运算符时,两个操作数都要传递给运算符函数。【例7.2】用友元运算符函数进行复数运算。15运算符重载#includeiostream.hclassComplex{private:doublereal,imag;public:friendComplexoperator+(Complexc1,Complexc2);friendComplexoperator-(Complexc1,Complexc2);friendComplexoperator*(Complexc1,Complexc2);Complex(doubler=0,doublei=0);voidprint();};16运算符重载Complex::Complex(doubler,doublei){real=r;imag=i;}voidComplex::print(){coutreal;if(imag0)cout+;if(imag!=0)coutimagiendl;}Complexoperator+(Complexc1,Complexc2){Complextemp;temp.real=c1.real+c2.real;temp.imag=c1.imag+c2.imag;returntemp;}17运算符重载Complexoperator-(Complexc1,Complexc2){Complextemp;temp.real=c1.real-c2.real;temp.imag=c1.imag-c2.imag;returntemp;}Complexoperator*(Complexc1,Complexc2){Complextemp;temp.real=c1.real*c2.real-c1.imag*c2.imag;temp.imag=c1.real*c2.imag+c1.imag*c2.real;returntemp;}18运算符重载main(){Complexa(1,2),b(3.0,4.0),c,d,e;c=a+b;d=a-b;e=a*b;coutc=;c.print();coutd=;d.print();coute=;e.print();coutf=;f.print();return0;}程序运行结果为:c=4+6id=-2-2ie=-5+10i相当于函数调用“operator+(a,b)”总结:设有双目运算符@,如果要重载@为类的友元函数,则该友元函数也有两个参数,分别为运算符的两个运算对象。重载后,表达式oprd1@oprd2等同于调用函数operator@(oprd1,oprd2)。19运算符重载3.单目运算符重载单目运算符只有一个操作数。用友元函数重载单目运算符时,由于友元函数是外部函数,操作数都必须以参数的形式列出来。需要一个显式的操作数。【例7.3】用友元函数重载单目运算符“-”。20运算符重载#includeiostream.hclassAB{public:AB(intx=0,inty=0){a=x;b=y;}friendABoperator-(ABobj);voidprint();private:inta,b;};ABoperator-(ABobj){obj.a=-obj.a;obj.b=-obj.b;returnobj;}21运算符重载voidAB::print(){couta=ab=bendl;}main(){ABob1(50,60),ob2;ob1.print();ob2=-ob1;ob2.print();ob1.print();return0;}22运算符重载【例7.4】使用友元函数重载“++”、“--”运算符。#includeiostream.hclasscoord{public:coord(inti=0,intj=0){x=i;y=j;};voidprint();friendcoordoperator++(coordop);private:intx,y;};voidcoord::print(){coutx:x,y:yendl;}23运算符重载coordoperator++(coordop){++op.x;++op.y;returnop;}main(){coordob(10,20);ob.print();operator++(ob);ob.print();++ob;ob.print();return0;}24运算符重载7.2.2成员运算符函数在C++中,可以把运算符函数定义成某个类的成员函数,称为成员运算符函数。当作为成员函数进行重载时,它的左操作数必须是该成员函数所属类的一个对象,因为必须通过类的对象调用该类的成员函数。25运算符重载1.成员运算符函数定义的语法形式成员运算符函数的原型在类的内部声明格式如下:classX{//…返回类型operator运算符(形参表);//…}在类外定义成员运算符函数的格式如下:返回类型X::operator运算符(形参表){函数体}26运算符重载2.双目运算符重载为成员函数对双目运算符而言,成员运算符函数的形参表中仅有一个参数,它作为运算符的右操作数。必须通过类的对象调用该类的成员函数。此时当前调用者对象作为运算符的左操作数,它是通过this指针隐含地传递给函数的。【例7.6】采用成员运算符函数来完成例7.2中同样的工作。27运算符重载成员函数通过类的对象调用。成员函数中的this指针初始化为对象的首地址,通过this指针可以直接操作对象的数据成员。左操作数就是调用该运算符函数的对象。#includeiostream.hclassComplex{public:Complexoperator+(Complexc);Complexoperator-(Complexc);Complex(doubler=0,doublei=0);voidprint();private:doublereal,imag;};28运算符重载Complex::Complex(doubler,doublei){real=r;imag=i;}voidComplex::print(){coutreal;if(imag0)cout+;if(imag!=0)coutimagiendl;}29运算符重载ComplexComplex::operator+(Complexc){Complextemp;temp.real=real+c.real;temp.imag=imag+c.imag;returntemp;}ComplexComplex::operator-(Complexc){Complextemp;temp.real=real-c.real;temp.imag=imag-c.i
本文标题:第7章 运算符重载
链接地址:https://www.777doc.com/doc-3383900 .html