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、义数据类型终究是有限的,我们在解决多种多样的实际问题 时,往往需要使用许多的自定义数据类型。例如,在解决科学与工程计算问题时,往往要使用复数、矩阵等。,下面定义一个简化的复数类complex class complex public: 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类类型不是预定义的基本数据类型,而是用户自
3、定义的数据类型。C+知道如何相加两个int数据,或相加两个float型数据,甚至知道如何把一个int型数据与一个float型数据相加,但是C+并不知道怎样将两个complex类类型的对象进行相加,这样需要我们来重载“+”运算符来解决两对象相加的问题,运算符重载的定义格式: operator () ; 在编译时遇到operator的运算符函数,就检查传递给函数的参数的类型。如果编译器在一个运算符的两边有自定义的数据类型。就执行用户自己的函数,而不是内部运算符的常规程序。 那么上例中的错误,就是需要重载重载+运算符,其运算符函数operator+()如下:,complex operator+(co
4、mplex com1,complex com2) complex temp; 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,#include class complex public: complex(double r=0.0,double i=0.0); void print (); friend complex operator+
8、(complex a,complex b); friend complex operator-(complex a,complex b); 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); comple
9、x 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; 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.im
10、ag+imag*b.real; return temp; complex operator/(complex a,complex b); complex temp; double t; t=1/(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) coutimag“in“;,int main()
11、 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(); 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
12、temp; 在这个函数中,先用类的构造函数来生成一个临时对象temp,执行return 语句时会调用拷贝构造函数,把temp的值拷贝到主调函数中的一个无名对象中。当函数operator+()结束时,会调用析构函数析构对象temp。这个过程程序开销较大,于是可以将上述程序改为:直接用类的构造函数来生成一个临时对象,而不对该对象进行命名。则上述程序段可以改为:,complex operator+(complex com1,complex com2) return complex(com1.real+com2.real,com1.imag+com2.imag; 这种方法是直接将一个无名临时对象创建到
13、主调函数中,那么运行效率高于前一种。,单目运算符重载 用友元函数重载单目运算符时,需要一个显式的操作数,例7-3中,用友元函数重载单目运算符“-” #include class nclass int a,b; public: nclass(int x=0,int y=0) a=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() cout“a=“a“ b“
14、b; main() nclass ob1(10,20),ob2; ob1.show(); ob2=-ob1; ob2.show(); return 0; ,使用友元函数重载“+”,“-”单目运算符时,可能会出现一些错误。如7-4 #include class coord public: coord(int i=0,int 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:
15、“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指针。如果该函数采用传值的方法传递参数,函数中对对象的任何修改均不影响调用该函数的对象本身。即在operator+( )函数中,任何内容的改变不会影响产生调用的操作数,也就是对象的数据成员x和y并未增加。为了解决这个问题可采用引用参数传递操作数。
16、那么例7.4怎么进行修改呢? 有关友元函数重载单目运算符后缀方式的表示方法,将在后面介绍,说明 运算符重载函数 operator()可以返回任何类型,甚至可以是 void类型,但通常返回类型与它所操作的类的类型相同,这样可使重载运算符用在复杂的表达式中。例如,在例7-2中,可以将几个复数连续进行加、减、乘、除的运算。 在重载运算符时,运算符函数所作的操作不一定要保持C+中该运算符原有的含义。例如,可以把加运算符重载成减操作,但这样容易造成混乱。所以保持原含义, 容易被接受,也符合人们的习惯。 在C+中,用户不能定义新的运算符,只能从C+己有的运算符中选择一个恰当的运算符重载。,C+编译器根据参
17、数的个数和类型来决定调用哪个重载函数。因此,可以为同一个运算符定义几个运算符重载函数来进行不同的操作。 不能用友元函数重载的运算符是:=,(),- 由于单目运算符“”可不改变操作数自身的值,所以在例7.3重载单目运算符“” 的友元运算符函数的原型可写成: friend AB operator(AB obj); 通过传值的方式传送参数。,成员运算符函数 定义 成员运算符函数定义的形式与类外的运算符函数定义基本相同,只是前者定义在类中。如 class X / type operator(参数表) / /.; 如果成员运算符函数声明在类中,而定义在类外,其格式为: type X:operator(参
18、数表) /函数体,其中,type()指定了重载运算符的返回值类型,operator是定义运算符重载函数的关键词,()给定了要重载的运算符名称,是C+中可重载的运算符,形参表中给出重载运算符所需要的参数和类型 根据运算符函数中重载操作数的不同,可将运算符分为单目运算符与双目运算符。若为双目运算符,则成员运算符函数的参数表中,则只有一个参数,若为单目运算符,则参数表中为空。 双目运算符而言,成员运算符函数的参数中表仅有一个参数,它作为运算符的右操作数,此时当前对象作为运算符的左操作数。它是通过this指针隐含地传递给函数的。例如: class X /;type operator +(X a); 例
19、7.6(双目运算符函数的重载来完成7.2中的工作),#include class complex double 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.imag; return temp; complex operator-(complex c) complex temp; temp.real=r
20、eal-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 c) complex temp; double t; t=1/(c.real*c.real+c.imag*c.i
21、mag); 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) coutimag“i“endl; 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(); A4.pr
22、int(); 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指针隐含地传递的。 一般而言,采用成员函数重载双目运算符后,可以
23、用两种方法来使用: aabb /隐式调用 aa.operator(bb)/显式调用 成员运算符函数operator所需要的一个操作数由当前调用成员运算符函数的对象aa通过this指针隐含地传递。因此,它的参数表中只有一个操作数bb,单目运算符函数重载 对单目运算符而言,成员运算符函数的参数表中没有参数,此时当前对象作为运算符的一个操作数,如下例: #include class coord int x,y; public : coord(int i=0,int j=0); void print(); coord operator+(); coord:coord(int i,int j ) x=i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 运算 重载 各类 详细 介绍
链接地址:https://www.31doc.com/p-1995391.html