第11讲运算符重载1_第1页
第11讲运算符重载1_第2页
第11讲运算符重载1_第3页
第11讲运算符重载1_第4页
第11讲运算符重载1_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+程序设计第11讲 运算符重载(1)运算符重载的概念运算符重载的概念运算符重载的规则运算符重载的规则重载为成员函数重载为成员函数双目运算符重载双目运算符重载复习函数重载复习函数重载函数名相同,区别在于函数参数的个数函数名相同,区别在于函数参数的个数和参数的类型。和参数的类型。一、一、 运算符重载的概念运算符重载的概念为处理复数如为处理复数如c1=3+4i,c2=5-10i,可定义如下的类:,可定义如下的类:class Complexpublic: Complex(double r=0,double i=0) real=r; imag=i; void disp() cout(real,imag

2、)endl; private: double real, imag; ;int main() Complex c1(3,4),c2(5,-10); coutc1=; c1.disp(); coutc2=; c2.disp(); return 0;实部和虚部实部和虚部带默认参数的构造函数带默认参数的构造函数显示复数对象显示复数对象c1的值的值定义两个复数对象定义两个复数对象显示对象值的函数显示对象值的函数显示复数对象显示复数对象c2的值的值现在考虑如何进行复数的加法:现在考虑如何进行复数的加法:c3=c1+c2。在在main函数中增加以下语句能完成任务吗?函数中增加以下语句能完成任务吗?int

3、main() Complex c1(3,4),c2(5,-10); coutc1=; c1.disp(); coutc2=; c2.disp(); Complex c3=c1+c2; coutc3=; c3.disp(); return 0;失败!失败!可以考虑定义一个专门的函数来实现复数相加,共有两种可以考虑定义一个专门的函数来实现复数相加,共有两种方案。方案。方案方案1: 利用友元函数实现复数相加。利用友元函数实现复数相加。class Complex ;int main() friend Complex add(Complex& f1, Complex& f2);Complex add(C

4、omplex& f1, Complex& f2) Complex t; t.real=f1.real+f2.real; t.imag=f1.imag+f2.imag; return t;定义一个普通函数定义一个普通函数实现复数相加实现复数相加声明为声明为Complex类的友元函数类的友元函数 Complex c3=add(c1, c2); coutc3=; c3.disp();调用调用add函数返回复数之和函数返回复数之和方案方案2: 利用成员函数实现复数相加。利用成员函数实现复数相加。class Complex ;int main() Complex c1(3,4),c2(5,-10); C

5、omplex add(Complex& f2);Complex Complex:add( Complex& f2) Complex t; t.real=real+f2.real; t.imag=imag+f2.imag; return t;定义一个成员函数定义一个成员函数实现复数相加实现复数相加声明为声明为Complex类的成员函数类的成员函数 Complex c3=c1.add(c2); coutc3=; c3.disp();通过通过c1调用调用add进行复数对象进行复数对象的相加,并以的相加,并以c2为实参为实参不论是友元函数方案,还是成员函数方案都具有不论是友元函数方案,还是成员函数方案

6、都具有调用方式繁琐、不直观调用方式繁琐、不直观的缺点。的缺点。人们希望在人们希望在C+程序中,能像整数、实数那样将程序中,能像整数、实数那样将复数直接相加。复数直接相加。Complex c3=add(c1, c2);/友元函数方案友元函数方案Complex c3=c1.add(c2); /成员函数方案成员函数方案Complex c3=c1 + c2;利用运算符重载,可以实现这个愿望。利用运算符重载,可以实现这个愿望。所谓运算符重载就是所谓运算符重载就是对已有的运算符赋予新的含对已有的运算符赋予新的含义,使其能够作用于某类的对象上义,使其能够作用于某类的对象上。二、二、 运算符重载的方法运算符重

7、载的方法运算符重载的方法是定义一个运算符重载的方法是定义一个特殊特殊的函数的函数,当程序中遇到,当程序中遇到含有该重载运算符的表达式时,系统就自动调用该函数以实现含有该重载运算符的表达式时,系统就自动调用该函数以实现相应的运算。相应的运算。这种特殊函数称为这种特殊函数称为运算符重载函数运算符重载函数,通常为,通常为类的成员函数类的成员函数.Complex Complex:operator+(Complex& f2)Complex t;t.real=real+f2.real;t.imag=imag+f2.imag;return t;要对要对Complex类重载加法运算符类重载加法运算符“+”,

8、可定义运算符重载可定义运算符重载函数如下:函数如下:运算符重载函数名运算符重载函数名运算符重载的方法运算符重载的方法 定义运算符重载函数的一般格式为:定义运算符重载函数的一般格式为:函数类型函数类型 类名类名:operator重载的运算符名重载的运算符名( (形参列表形参列表) ) /函数体函数体 其中其中operator是关键字是关键字,它,它与重载的运算符一起构成与重载的运算符一起构成函数名函数名。函数名函数名 可以看出,定义运算符重载函数与定义普通函数可以看出,定义运算符重载函数与定义普通函数类似。由于函数名的特殊性,编译器也容易与其他函类似。由于函数名的特殊性,编译器也容易与其他函数区

9、分。数区分。例如重载运算符例如重载运算符“”,只需要定义名字为只需要定义名字为operator(形参列表形参列表)的函数就可以了。)的函数就可以了。class Complexpublic:Complex(double r=0,double i=0)real=r;imag=i;void disp()cout(real,imag)endl;/ Complex add(Complex& f2); Complex operator+ (Complex &f2); private:double real,imag;声明复数对象相加的声明复数对象相加的成员函数成员函数声明复数对象相加的声明复数对象相加的运

10、算符重载函数运算符重载函数例、对复数类重载加法运算符。例、对复数类重载加法运算符。 只需在成员函数方案基础上稍作修改即可。只需在成员函数方案基础上稍作修改即可。/Complex Complex:add(Complex& f2) Complex Complex:operator+(Complex& f2) Complex t;t.real=real+f2.real;t.imag=imag+f2.imag;return t;定义加法运算符重载函数定义加法运算符重载函数它只有一个形参它只有一个形参int main()Complex c1(3,4),c2(5,-10);coutc1=; c1.disp

11、();coutc2=; c2.disp();/Complex c3=c1.add(c2);coutc3=; c3.disp();return 0;类对象成员类对象成员real、imag为为 第第1个操作数对象的成员个操作数对象的成员通过通过c1调用调用add进行复数对象进行复数对象的相加,并以的相加,并以c2为实参为实参c1+c2被解释为被解释为c1.operator+(c2)Complex c3=c1 + c2;运算符重载的方法运算符重载的方法 请同学们自己完成对复数类的请同学们自己完成对复数类的*、/等双目等双目运算符的重载。运算符的重载。 优点:优点: 能使能使C+程序易于编写、阅读及维

12、护;程序易于编写、阅读及维护; 运算符重载使运算符重载使C+具有了更强大的功能和更具有了更强大的功能和更好的可扩充性。好的可扩充性。 注意:注意:运算符被重载后,其原有的功能运算符被重载后,其原有的功能仍然保留,没有丧失或改变。仍然保留,没有丧失或改变。运算符重载运算符重载规则和限制规则和限制 下列运算符不能重载:下列运算符不能重载:. (成员访问运算符成员访问运算符) .* (成员指针访问运算符成员指针访问运算符) : (域运算符域运算符) ?: (条件运算符条件运算符) sizeof (长度运算符长度运算符) 只能重载只能重载C+语言中已有的运算符,不可臆造新的。语言中已有的运算符,不可臆

13、造新的。 不改变原运算符的优先级和结合性。不改变原运算符的优先级和结合性。 不能改变操作数个数。不能改变操作数个数。 重载运算符的函数不能有默认的参数,否则就改变了运重载运算符的函数不能有默认的参数,否则就改变了运算符的目数。算符的目数。 重载的运算符必须与用户自定义类型的对象重载的运算符必须与用户自定义类型的对象一起使用,其参数至少应有一个是类对象或一起使用,其参数至少应有一个是类对象或类对象的引用。就是说,参数不能全部是类对象的引用。就是说,参数不能全部是C+的标准类型,以防止用户修改用于标准的标准类型,以防止用户修改用于标准类型数据运算符的性质(可防止把整数的加类型数据运算符的性质(可防

14、止把整数的加法改为减法)。法改为减法)。例如:以下是错的。例如:以下是错的。int operator +(int a,int b) return (a-b);运算符重载的几个问题运算符重载的几个问题1、可以重载的运算符、可以重载的运算符 算术运算符:算术运算符:+、-、*、/、%、+、-; 位操作运算符:位操作运算符:&、|、; 逻辑运算符:逻辑运算符:!、&、|; 比较运算符:比较运算符:、=、=、=、!=; 赋值运算符:赋值运算符:=、+=、-=、*=、/=、%=、 &=、|=、=、=; 其他运算符:其他运算符:、()、-、 、new、delete、 new、delete、-*;运算符重载

15、的几个问题运算符重载的几个问题(续续)2、编译程序如何选用哪一个运算符函数?、编译程序如何选用哪一个运算符函数?运算符实质上是函数,遵循函数重载原则;运算符实质上是函数,遵循函数重载原则;3、运算符重载时必须遵循哪些原则?、运算符重载时必须遵循哪些原则? 重载运算符含义必须清楚;重载运算符含义必须清楚; 重载运算符不能有二义性;重载运算符不能有二义性;4、重载运算符有哪些限制?、重载运算符有哪些限制? 不可臆造新的运算符;不可臆造新的运算符; 重载运算符坚持重载运算符坚持4个个“不能改变不能改变”:运算符重载的几个问题运算符重载的几个问题(续续)k不能改变运算符操作数的个数;不能改变运算符操作

16、数的个数;k不能改变运算符原有的优先级;不能改变运算符原有的优先级;k不能改变运算符原有的结合性;不能改变运算符原有的结合性;k不能改变运算符原有的语法结构;不能改变运算符原有的语法结构; 用于类对象的运算符一般必须重载,但用于类对象的运算符一般必须重载,但“=”和和“&”可不必重载。可不必重载。 赋值运算符(赋值运算符(=)可以用于同类对象之间相互赋可以用于同类对象之间相互赋值。值。 地址运算符(地址运算符(&)能返回类对象在内存中的地能返回类对象在内存中的地址。址。 应当使重载运算符的功能类似于该运算符作用于应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能。标准类型数据

17、时所实现的功能。 运算符重载函数可以是类的成员函数,也可以是运算符重载函数可以是类的成员函数,也可以是类的友员函数,还可以是普通函数。类的友员函数,还可以是普通函数。三、运算符重载函数的两种形式三、运算符重载函数的两种形式1、重载为类的成员函数、重载为类的成员函数 重载重载一元(单目)一元(单目)运算符,运算符,不不再再显式说明参数显式说明参数; 重载重载二元(双目)二元(双目)运算符,只运算符,只显式说明一个参数显式说明一个参数;该;该参数为操作数的参数为操作数的右操作数右操作数,左操作数左操作数由由this指针指针(指(指向调用向调用 该成员函数的对象)提供;该成员函数的对象)提供; 重载

18、为成员函数时,隐含了一个参数重载为成员函数时,隐含了一个参数(this指针指针); 重载为类成员函数。重载为类成员函数。 重载为友元函数。重载为友元函数。参数个数参数个数=原操作数个数原操作数个数-1(后置(后置+、- -除外)除外)运算符重载的方法运算符重载的方法 重载双目运算符重载双目运算符 双目运算符的运算符重载函数只有一双目运算符的运算符重载函数只有一个形参,用来接收第个形参,用来接收第2个操作数,运算符重个操作数,运算符重载函数中的类对象成员就是载函数中的类对象成员就是第第1个操作数的个操作数的数据成员。数据成员。 双目运算符双目运算符 B如果要重载如果要重载 B 为类成员函数,使之

19、能够实现表为类成员函数,使之能够实现表达式达式 oprd1 B oprd2,其中,其中 oprd1 为为A 类对类对象,则象,则 B 应被重载为应被重载为 A 类的成员函数,形参类的成员函数,形参类型应该是类型应该是 oprd2 所属的类型。所属的类型。经重载后,表达式经重载后,表达式 oprd1 B oprd2 相当于相当于 oprd1.operator B(oprd2) 例:将例:将“+”、“-”运算重载为复数类的成员运算重载为复数类的成员函数。函数。 规则规则:实部和虚部分别相加减。实部和虚部分别相加减。 操作数操作数:两个操作数都是复数类的对象。两个操作数都是复数类的对象。例:分析下列

20、程序的输出结果。例:分析下列程序的输出结果。#include class complexpublic: complex(double r=0,double i=0); complex operator +(const complex& c); complex operator -(const complex& c); complex operator -(); void print() const;private: double real,imag;complex:complex(double r,double i)+运算符运算符-运算符运算符求负运算符求负运算符 real=r; imag=i

21、;complex complex:operator +(const complex& c) double r=real+c.real; double i=imag+c.imag; return complex(r,i);complex complex:operator -(const complex& c) double r=real-c.real; double i=imag-c.imag; return complex(r,i);complex complex:operator -() return complex(-real,-imag);void complex:print() con

22、st cout (real, imag) endl;void main() complex c1(2.5,3.7),c2(4.2,6.5); complex c; c=c1-c2; c.print(); c=c1+c2;c=c1.operator -(c2);c=c1.operator +(c2); c.print(); c=-c1; c.print();输输出出(-1.7,-2.8)(6.7,10.2)(-2.5,-3.7)c=c1.operator -();例:指出程序中的错误,并改正。例:指出程序中的错误,并改正。class integerpublic: integer(int i=0)

23、 value=i; integer operator +(integer i) return integer(value+=i.value); private: int value;void main() integer i1=10; integer i2=i1+5; integer i3=3+i2;错误错误原因原因:3+i2等价于等价于3.operator +(i2)运算符重载的方法运算符重载的方法 重载单目运算符重载单目运算符 单目运算符的运算符重载函数没有单目运算符的运算符重载函数没有形参,函数中的类对象成员就是形参,函数中的类对象成员就是操作数操作数的数据成员的数据成员。 运算符成员函

24、数的设计运算符成员函数的设计 前置单目运算符前置单目运算符 U(例(例 +i,-i)如果要重载如果要重载 U 为类成员函数,使之能够实为类成员函数,使之能够实现表达式现表达式 U oprd,其中,其中 oprd 为为A类对象,类对象,则则 U 应被重载为应被重载为 A 类的成员函数,无形参。类的成员函数,无形参。经重载后,经重载后,表达式表达式 U oprd 相当于相当于 oprd.operator U()运算符成员函数的设计运算符成员函数的设计 后置单目运算符后置单目运算符 +和和- (例(例i+,i-) 如果要重载如果要重载 +或或-为类成员函数,使之能够为类成员函数,使之能够实现表达式实

25、现表达式 oprd+ 或或 oprd- ,其中,其中 oprd 为为A类对象,则类对象,则 +或或- 应被重载为应被重载为 A 类的成类的成员函数,且具有一个员函数,且具有一个 int 类型类型形参(形参(区别于前区别于前置单目运算符置单目运算符+和和- )。)。 经重载后,表达式经重载后,表达式 oprd+ 相当于相当于 oprd.operator +(0)运算符重载示例运算符重载示例例:例:+运算符。运算符。#include class counterpublic: counter() value=0; counter operator +(); counter operator +(in

26、t); void display() coutvalueendl;private: int value;counter counter:operator +() value+;前置运算符前置运算符后置运算符后置运算符运算符重载示例(续)运算符重载示例(续) return *this;counter counter:operator +(int i) counter t; t.value=value+; return t;void main() counter c; c.display(); for(int i=0;i10;i+) c+; c.display();后置运算符变量值加后置运算符变量

27、值加1,表达式值不,表达式值不变变前置运算符变量值与表达式值均加前置运算符变量值与表达式值均加1c.operator +(0);运算符重载示例(续)运算符重载示例(续) for(i=0;i10;i+) +c; c.display();输输出出01020c.operator +();书中书中329页例页例10.6例例 运算符前置运算符前置+和后置和后置+重载为时钟类重载为时钟类的成员函数。的成员函数。 前置单目运算符,重载函数没有形参,前置单目运算符,重载函数没有形参,对于后置单目运算符,重载函数需要有对于后置单目运算符,重载函数需要有一个整型形参。一个整型形参。 操作数是时钟类的对象。操作数是时钟类的对象。 实现时间增加实现时间增加1秒钟。秒钟。运算符重载运算符重载#include

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论