C运算符重载各类详细介绍.ppt
《C运算符重载各类详细介绍.ppt》由会员分享,可在线阅读,更多相关《C运算符重载各类详细介绍.ppt(60页珍藏版)》请在三一办公上搜索。
1、第7章 运算符重载,本章主要内容7.1 引入运算符重载的原因及运算符重载的规则7.2 运算符重载函数的两种形式7.3 几种常用运算符的重载7.4 类型转换本章重点几种常用运算符的重载与类型转换本章难点单目运算符“+”与“”的重载本章所需学时:4学时,7.1 运算符重载概述,引入运算符重载的原因例如:int a=1,b=2;float c=1.1,d=2.4;int e=a+b;float f=c+d;float g=f+e;为什么同一个运算符“”可以用于完成不同类型的数据的加运算呢?原来C+语言针对预定义数据类型已经对某些运算符做了适当的重载。C+语言提供的预定义数据类型终究是有限的,我们在解
2、决多种多样的实际问题 时,往往需要使用许多的自定义数据类型。例如,在解决科学与工程计算问题时,往往要使用复数、矩阵等。,下面定义一个简化的复数类complexclass complexpublic:double real,imag;complex(double r=0,double i=0)real=r,imag=i;main()complex com1(1.1,2.2),com2(3.3,4.4),total;total=com1+com2;/错误/return 0;,错误原因在于complex类类型不是预定义的基本数据类型,而是用户自定义的数据类型。C+知道如何相加两个int数据,或相加两
3、个float型数据,甚至知道如何把一个int型数据与一个float型数据相加,但是C+并不知道怎样将两个complex类类型的对象进行相加,这样需要我们来重载“+”运算符来解决两对象相加的问题,运算符重载的定义格式:operator();在编译时遇到operator的运算符函数,就检查传递给函数的参数的类型。如果编译器在一个运算符的两边有自定义的数据类型。就执行用户自己的函数,而不是内部运算符的常规程序。那么上例中的错误,就是需要重载重载+运算符,其运算符函数operator+()如下:,complex operator+(complex com1,complex com2)complex t
4、emp;temp.real=com1.real+com2.real;temp.real=com1.imag+com2.imag;return temp;其中主函数的 total=com1+com2;(隐式调用)语句也可以写成:total=operator+(com1,com2);(显式调用)从中可以看出运算符重载进一步提高了面向对象软件系统的灵活性、可扩充性和可读性,运算符重载的规则重载运算符与预定义运算符的使用方法完全相同,被重载的运算符不改变原来的操作数个数、优先级和结合性。重载的运算符只能是运算符集中的运算符,不能另创新的运算符。运算符的含义可以改变,但最好不改变。如实数的加法运算可以用
5、乘法运算符来实现在C+中,大多数系统预定义运算符可以把被重载,但也有些运算符不能被重载如:类属关系运算符“”、成员指针运算符“”、作用域分辨符“:”、sizeof运算符和 三目运算符“?:”不能改变运算符对预定义类型的操作方式,7.2 运算符重载两种形式,运算符重载与函数重载相似,其目的是设置某一运算符,让它具有另一种功能,尽管此运算符在原先C+语言中代表另一种含义,但他们彼此之间并不冲突。C+会根据运算符中的操作数来辨别应使用哪一种功能进行运算。在类外定义运算符重载函数,只能对类公有数据成员进行操作。实际上,运算符的重载有两种形式:定义为类的类友元函数;定义为它将要操作的类的成员函数。前者称
6、为友元运算符函数,后者为成员运算符函数。,友元运算符函数概念友元运算符函数定义的语法形式声明friend type operator(形数表);定义 type operator(形数表)/函数体其中,type()指定了重载运算符的返回值类型,operator是定义运算符重载函数的关键词,()给定了要重载的运算符名称,是C+中可重载的运算符,形参表中给出重载运算符所需要的参数和类型由于友元运算符函数不是类的成员函数,所以没有this指针。如果重载的运算符函数是双目的运算符,则参数表中有两个操作数,若为单目运算符,则参数表中有一个操作数,双目运算符重载当用友元函数重载双目运算符时,两个操作数都要传
7、递给运算符函数。一般而言,采用友元函数重载双目运算符后,也可以采用两种方法使用:aabb/隐式调用aa.operator(bb)/显式调用双目友元运算函数operator所需的两个操作数都在参数表中由对象aa和bb显式提供用友元运算符函数进行复数运算,见例7-2,#includeclass complexpublic:complex(double r=0.0,double i=0.0);void print();friend complex operator+(complex a,complex b);friend complex operator-(complex a,complex b);
8、friend complex operator*(complex a,complex b);friend complex operator/(complex a,complex b);private:double real;double imag;,complex:complex(double r,double i);real=r;imag=i;complex operator+(complex a,complex b);complex temp;temp.real=a.real+b.real;temp.imag=a.imag+b.imag;return temp;complex operat
9、or-(complex a,complex b);complex temp;temp.real=a.real-b.real;temp.imag=a.imag-b.imag;return temp;complex operator*(complex a,complex b);complex temp;temp.real=a.real*b.real-imag*b.imag;temp.imag=a.real*b.imag+imag*b.real;return temp;complex operator/(complex a,complex b);complex temp;double t;t=1/(
10、b.real*b.real+b.imag*b.imag);temp.real=(a.real+b.real+a.imag*b.imag)*t;temp.imag=(b.real+a.real-a.imag*b.imag)*t;return temp;void complex:print()cout0)cout+;if(imag!=0)coutimagin;,int main()complex A1(2,3,4.6).A2(3.6,2.8),A3,A4,A5,A6;A3=A1+A2;A4=A1-A2;A5=A1*A2;A6=A1/A2;A1.print();A2.print();A3.print
11、();A4.print();A5.print();A6.print();return 0;,说明complex operator+(complex com1,complex com2)complex temp;temp.real=com1.real+com2.real;temp.real=com1.imag+com2.imag;return temp;在这个函数中,先用类的构造函数来生成一个临时对象temp,执行return 语句时会调用拷贝构造函数,把temp的值拷贝到主调函数中的一个无名对象中。当函数operator+()结束时,会调用析构函数析构对象temp。这个过程程序开销较大,于是可
12、以将上述程序改为:直接用类的构造函数来生成一个临时对象,而不对该对象进行命名。则上述程序段可以改为:,complex operator+(complex com1,complex com2)return complex(com1.real+com2.real,com1.imag+com2.imag;这种方法是直接将一个无名临时对象创建到主调函数中,那么运行效率高于前一种。,单目运算符重载用友元函数重载单目运算符时,需要一个显式的操作数,例7-3中,用友元函数重载单目运算符“-”#includeclass nclassint a,b;public:nclass(int x=0,int y=0)a
13、=x;b=y;friend nclass operator-(nclass obj);void show();,nclass operator-(nclass obj)obj.a=-obj.a;obj.b=-obj.b;return obj;void nclass:show()couta=a bb;main()nclass ob1(10,20),ob2;ob1.show();ob2=-ob1;ob2.show();return 0;,使用友元函数重载“+”,“-”单目运算符时,可能会出现一些错误。如7-4#includeclass coord public:coord(int i=0,int
14、j=0);void print();friend coord operator+(coord op);private:int x,y;,coord:coord(int i,int j)x=i;y=j;void coord:print()cout x:x y yendl;coord operator+(coord op)+op.x;+op.y;return op;main()coord ob(10,20);ob.print();operator+(ob);ob.print();+ob;ob.print();return 0;,由于友元函数不是类的成员,所以没有this指针。如果该函数采用传值的方
15、法传递参数,函数中对对象的任何修改均不影响调用该函数的对象本身。即在operator+()函数中,任何内容的改变不会影响产生调用的操作数,也就是对象的数据成员x和y并未增加。为了解决这个问题可采用引用参数传递操作数。那么例7.4怎么进行修改呢?有关友元函数重载单目运算符后缀方式的表示方法,将在后面介绍,说明运算符重载函数 operator()可以返回任何类型,甚至可以是 void类型,但通常返回类型与它所操作的类的类型相同,这样可使重载运算符用在复杂的表达式中。例如,在例7-2中,可以将几个复数连续进行加、减、乘、除的运算。在重载运算符时,运算符函数所作的操作不一定要保持C+中该运算符原有的含
16、义。例如,可以把加运算符重载成减操作,但这样容易造成混乱。所以保持原含义,容易被接受,也符合人们的习惯。在C+中,用户不能定义新的运算符,只能从C+己有的运算符中选择一个恰当的运算符重载。,C+编译器根据参数的个数和类型来决定调用哪个重载函数。因此,可以为同一个运算符定义几个运算符重载函数来进行不同的操作。不能用友元函数重载的运算符是:=,(),-由于单目运算符“”可不改变操作数自身的值,所以在例7.3重载单目运算符“”的友元运算符函数的原型可写成:friend AB operator(AB obj);通过传值的方式传送参数。,成员运算符函数定义成员运算符函数定义的形式与类外的运算符函数定义基
17、本相同,只是前者定义在类中。如 class X/type operator(参数表)/.;如果成员运算符函数声明在类中,而定义在类外,其格式为:type X:operator(参数表)/函数体,其中,type()指定了重载运算符的返回值类型,operator是定义运算符重载函数的关键词,()给定了要重载的运算符名称,是C+中可重载的运算符,形参表中给出重载运算符所需要的参数和类型根据运算符函数中重载操作数的不同,可将运算符分为单目运算符与双目运算符。若为双目运算符,则成员运算符函数的参数表中,则只有一个参数,若为单目运算符,则参数表中为空。双目运算符而言,成员运算符函数的参数中表仅有一个参数,
18、它作为运算符的右操作数,此时当前对象作为运算符的左操作数。它是通过this指针隐含地传递给函数的。例如:class X/;type operator+(X a);例7.6(双目运算符函数的重载来完成7.2中的工作),#include class complexdouble real;double imag;public:complex(double r=0,double i=0)real=r;imag=i;void print();complex operator+(complex c)complex temp;temp.real=real+c.real;temp.imag=imag+c.im
19、ag;return temp;complex operator-(complex c)complex temp;temp.real=real-c.real;temp.imag=imag-c.imag;return temp;complex operator*(complex c)complex temp;temp.real=(real*c.real-imag*c.imag);temp.imag=(real*c.imag+c.real*imag);return temp;complex operator/(complex c);,complex complex:operator/(complex
20、 c)complex temp;double t;t=1/(c.real*c.real+c.imag*c.imag);temp.real=(real*c.real+imag*c.imag)*t;temp.imag=(imag*c.real-real*c.imag)*t;return temp;void complex:print()cout0)cout+;if(imag!=0)coutimagiendl;int main()complex A1(2.3,4.6),A2(3.6,2.8),A3,A4,A5,A6;A3=A1+A2;A4=A1-A2;A5=A1*A2;A6=A1/A2;A1.pri
21、nt();A2.print();A3.print();A4.print();A5.print();A6.print();return 0;,在主函数中A3=A1+A2;A4=A1-A2;A5=A1*A2;A6=A1/A2;程序执行到这四条语句时,C+将其解释为 A3=A1.operator+(A2);A4=A1.operator-(A2);A5=A1.operator*(A2);A6=A1.operator/(A2);由此可知,成员运算符函数operator 实际上是由双目运算符的 左边对象A1调用的。尽管参数表中只有一个操作数A2,但另一个操作数是由对象A1通过this指针隐含地传递的。一般
22、而言,采用成员函数重载双目运算符后,可以用两种方法来使用:aabb/隐式调用 aa.operator(bb)/显式调用 成员运算符函数operator所需要的一个操作数由当前调用成员运算符函数的对象aa通过this指针隐含地传递。因此,它的参数表中只有一个操作数bb,单目运算符函数重载对单目运算符而言,成员运算符函数的参数表中没有参数,此时当前对象作为运算符的一个操作数,如下例:#include class coordint x,y;public:coord(int i=0,int j=0);void print();coord operator+();coord:coord(int i,in
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 运算 重载 各类 详细 介绍

链接地址:https://www.31ppt.com/p-4593857.html