第13章 运算符重载

上传人:pu****.1 文档编号:568007417 上传时间:2024-07-23 格式:PPT 页数:49 大小:311.50KB
返回 下载 相关 举报
第13章 运算符重载_第1页
第1页 / 共49页
第13章 运算符重载_第2页
第2页 / 共49页
第13章 运算符重载_第3页
第3页 / 共49页
第13章 运算符重载_第4页
第4页 / 共49页
第13章 运算符重载_第5页
第5页 / 共49页
点击查看更多>>
资源描述

《第13章 运算符重载》由会员分享,可在线阅读,更多相关《第13章 运算符重载(49页珍藏版)》请在金锄头文库上搜索。

1、第十三章第十三章 运算符重载运算符重载1函数的重载函数的重载所谓函数的重载是指完成不同功能的函数可以具所谓函数的重载是指完成不同功能的函数可以具有有相同的函数名相同的函数名。 C+的编译器是根据的编译器是根据函数的实参函数的实参来确定应该调用来确定应该调用哪一个函数的。哪一个函数的。 int fun(int a, int b) return a+b; int fun (int a) return a*a; void main(void) coutfun(3,5)endl; coutfun(5)endl;8252 1、定定义义的的重重载载函函数数必必须须具具有有不不同同的的参参数数个个数数,或或

2、不不同同的的参参数数类类型型。只只有有这这样样编编译译系系统统才才有有可可能能根据不同的参数去调用不同的重载函数。根据不同的参数去调用不同的重载函数。2、仅返回值不同时,不能定义为重载函数。、仅返回值不同时,不能定义为重载函数。 3int sum,a=3,b=2;(int)=(int) + (int)sum=a+b; float add, x=3.2, y=2.5;(float)=(float) + (float)add=x+y; char str4, c12=a, c22=b;(char *)=(char *) + (char *)str=c1+c2; 编译系统中的运算符编译系统中的运算符“

3、”本身不能做这种运算,本身不能做这种运算,若使上式可以运算,必须重新定义若使上式可以运算,必须重新定义“”运算符,运算符,这种重新定义的过程成为运算符的重载。这种重新定义的过程成为运算符的重载。系统自动系统自动识别数据识别数据类型类型4class A float x,y;public: A(float a=0, float b=0) x=a; y=b; void main(void) A a(2,3), b(3,4), c; c=a+b;两对象不能使用,必须重新定义两对象不能使用,必须重新定义运算符重载就是赋予已有的运算符多重运算符重载就是赋予已有的运算符多重含义含义。C+通过重新定义运算符,

4、使它通过重新定义运算符,使它能够用于特定类的对象执行特定的功能能够用于特定类的对象执行特定的功能5运算符的重载从另一个方面体现了运算符的重载从另一个方面体现了OOP技术的多技术的多态性,态性,且同一运算符根据不同的运算对象可以完且同一运算符根据不同的运算对象可以完成不同的操作。成不同的操作。 为了重载运算符,必须定义一个函数,并告为了重载运算符,必须定义一个函数,并告诉编译器,诉编译器,遇到这个重载运算符就调用该函数,遇到这个重载运算符就调用该函数,由这个函数来完成该运算符应该完成的操作。由这个函数来完成该运算符应该完成的操作。这这种函数称为运算符重载函数,它通常是种函数称为运算符重载函数,它

5、通常是类的成员类的成员函数或者是友元函数函数或者是友元函数。运算符的操作数通常也应运算符的操作数通常也应该是类的对象。该是类的对象。6重载为类的重载为类的成员函数成员函数格式如下:格式如下: operator()函数体函数体A operator + (A &);/重载了类重载了类A的的“+”运算运算符符其中:其中:operator是定义运算符重载函数的关键字,是定义运算符重载函数的关键字,它与其后的运算符一起构成函数名。它与其后的运算符一起构成函数名。返回类型返回类型运算的对象运算的对象关键字关键字函数名函数名运算的对象运算的对象7class Aint i;public:A(int a=0)

6、i=a; void Show(void)couti=iendl;void AddA(A &a,A &b) /利用函数进行类之间的运算利用函数进行类之间的运算i=a.i+b.i;void main(void)A a1(10),a2(20),a3;a1.Show ();a2.Show ();/a3=a1+a2;/不可直接运算不可直接运算a3.AddA(a1,a2);/调用专门的功能函数调用专门的功能函数a3.Show ();没有重载运算符的例子没有重载运算符的例子利用函数完成了加法运算利用函数完成了加法运算用和作对象调用函数用和作对象调用函数8class Aint i;public:A(int a

7、=0) i=a;void Show(void)couti=iendl;void AddA(A &a, A &b)/利用函数进行类之间的运算利用函数进行类之间的运算i=a.i+b.i;A operator +(A &a) /重载运算符重载运算符+A t;t.i=i+a.i;return t;void main(void)A a1(10),a2(20),a3;a1.Show ();a2.Show ();a3=a1+a2;/重新解释了加法,可以直接进行类的运算重新解释了加法,可以直接进行类的运算a3.AddA(a1,a2);/调用专门的功能函数调用专门的功能函数a3.Show ();相当于相当于a3

8、=a1.operator+(a2)9重载运算符与一般函数的比较:重载运算符与一般函数的比较:相同:相同:1)均为类的成员函数;)均为类的成员函数;2)实现同一功能)实现同一功能void AddA(A &a, A &b)i=a.i+b.i; A operator +(A &a) A t; t.i=i+a.i; return t;a3=a1+a2;a3.AddA(a1,a2);返回值返回值函数名函数名形参列表形参列表由对象由对象a3调用调用函数调用:函数调用:返回值返回值函数名函数名形参形参函数调用:函数调用:a3=a1.operator+(a2);由对象由对象a1调用调用10A operator

9、 +(A &a) A t; t.i=i+a.i; return t;a3=a1+a2;返回值返回值函数名函数名形参形参函数调用:函数调用:a3=a1.operator+(a2);由对象由对象a1调用调用总结:总结:重新定义运算符,重新定义运算符,由左由左操作符调用右操作符操作符调用右操作符。最后将函数返回值赋给最后将函数返回值赋给运算结果的对象。运算结果的对象。11class Aint i;public:A(int a=0) i=a;void Show(void)couti=iendl;void AddA(A &a, A &b)/利用函数进行类之间的运算利用函数进行类之间的运算i=a.i+b.

10、i;A operator +(A &a) /重载运算符重载运算符+A t;t.i=i+a.i;return t;void main(void)A a1(10),a2(20),a3;a1.Show ();a2.Show ();a3=a1+a2;/重新解释了加法,可以直接进行类的运算重新解释了加法,可以直接进行类的运算a3.AddA(a1,a2);/调用专门的功能函数调用专门的功能函数a3.Show ();相当于相当于a3=a1.operator+(a2)12当当用用成成员员函函数数实实现现运运算算符符的的重重载载时时,运运算算符符重重载载函函数数的的参参数数只只能能有有二二种种情情况况:没没有有

11、参参数数或或带带有有一一个个参参数数。对对于于只只有有一一个个操操作作数数的的运运算算符符(如如+),在在重重载载这这种种运运算算符符时时,通通常常不不能能有有参参数数;而而对对于于有有二二个个操操作作数数的的运运算算符符,只只能能带带有有一一个个参参数数。这这参参数数可可以以是是对对象象,对对象象的的引引用用,或或其其它它类类型型的的参参数数。在在C+中中不不允许重载有三个操作数的运算符允许重载有三个操作数的运算符132、在在C+中中,允允许许重重载载的的运运算算符符列列于于表表13.1中。中。3、在、在C+中不允许重载的运算符列于中不允许重载的运算符列于表表13.2。4、只只能能对对C+中

12、中已已定定义义了了的的运运算算符符进进行行重重载载,而而且且,当当重重载载一一个个运运算算符符时时,该该运运算算符符的的优优先级和结合律是不能改变的先级和结合律是不能改变的。14class roomfloat Length;float Wide;public: room(float a=0.0,float b=0.0) Length=a; Wide=b; void Show(void)coutLength=LengthtWide=Wideendl; void ShowArea(void) coutArea=Length*Wideendl; room operator+(room &);/重载运

13、算符重载运算符+,函数原型,函数原型;room room:operator + (room &r) /重载运算符,函数定义重载运算符,函数定义 room rr; rr.Length =Length+r.Length; rr.Wide =Wide+r.Wide ; return rr;void main(void) room r1(3,2),r2(1,4), r3,r4; r1.Show ();r2.Show (); r3=r1+r2; r3.Show (); r4=r1+r2+r3;r4.Show ();r4=r1+r2+r3;(r1+r2); (r1+r2)+r3;r4=r1+(r2+r3)

14、;(r2+r3);r1+(r2+r3);运算符的优先级和结运算符的优先级和结合律是不能改变的合律是不能改变的15class Aint i;public:A(int a=0) i=a;void Show(void)couti=iendl;A operator +(A &a) /重载运算符重载运算符+A t;t.i=i+a.i;return t; void operator+=(A &a)i=i+a.i;void main(void)A a1(10),a2(20),a3;a1.Show ();a2.Show ();a3=a1+a2;a1+=a2;a3.Show ();由左操作符调用右操由左操作符调

15、用右操作符作符,没有返回值,没有返回值,故函数类型为故函数类型为void。相当于相当于a3=a1.operator+(a2)相当于相当于a1.operator+=(a2)16单目运算符的重载单目运算符的重载只具有一个操作数的运算符为单目运算符,最常用只具有一个操作数的运算符为单目运算符,最常用的为及。的为及。A a, b;b=+a;b=a+;A a;+a;a+;可以看出,虽然运算后对象可以看出,虽然运算后对象a a的值一致,但先自加的值一致,但先自加或后自加的或后自加的重载运算符函数的返回值不一致,重载运算符函数的返回值不一致,必须必须在重载时予以区分在重载时予以区分。17+为前置运算时,为前

16、置运算时,它的运算符重载函数的一般格式为:它的运算符重载函数的一般格式为: operator +( ) operator +( ) . .; +为后置运算时为后置运算时,它的运算符重载函数的一般格式为:,它的运算符重载函数的一般格式为: operator +( operator +(intint) ) . .; A a, b;b=+a;b=a+;A operator +( ) . A operator +(int) . 18class A float x, y;public: A(float a=0, float b=0) x=a; y=b; A operator +( )A t; t.x=+

17、 x; t.y=+y; return t; A operator +(int) A t; t.x=x+; t.y=y+; return t;void main(void) A a(2,3), b; b=+a; b=a+;19A operator +( ) A t; t.x=+ x; t.y=+y; return t; b=+a; b=a.operator+( );返回值返回值函数名函数名23at3344t作为函数值返回赋给作为函数值返回赋给bA operator +( ) + x; +y; return *this;将对象本身作为函将对象本身作为函数值返回赋给数值返回赋给b20A operat

18、or +(int) A t; t.x=x+; t.y=y+; return t;b=a+; b=a.operator+(3);23at3243返回值返回值函数名函数名t作为函数值返回赋给作为函数值返回赋给b21class incountint c1,c2;public: incount(int a=0,int b=0) c1=a; c2=b; void Show(void)coutc1=c1tc2=c2等等格式为:格式为:friend operator().c=a+b; / c=operator+( a, b)friend A operator + (A &a, A &b).26class A

19、int i;public:public:A(int a=0) i=a; void Show(void)couti=iendl; friend A operator +(A &,A &);/友元函数,两个参数,为引用友元函数,两个参数,为引用;A operator +(A &a , A &b)A t;t.i=a.i+b.i;return t; void main(void)A a1(10),a2(20),a3;a1.Show ();a2.Show ();a3=a1+a2;/重新解释了加法,可以直接进行类的运算重新解释了加法,可以直接进行类的运算a3.Show ();相当于相当于a3=operat

20、or+(a1,a2)27+为前置运算时,为前置运算时,它的运算符重载函数的一般格式为:它的运算符重载函数的一般格式为:A operator +(A &a)A operator +(A &a) . .; +为后置运算时为后置运算时,它的运算符重载函数的一般格式为:,它的运算符重载函数的一般格式为:A operator +(A &a, A operator +(A &a, intint) ) . .; A a, b;b=+a;b=a+;A operator +( A a ) . A operator +(A a, int) . 28class Aint i;public:public:A(int

21、a=0) i=a; void Show(void)couti=iendl;friend A operator+(A &a) a.i+; retrurn a;friend A operator+(A &a, int n) A t;t.i=a.i; a.i+; return t; ;void main(void)A a1(10),a2,a3;a2=+a1;a3=a1+;a2.Show();a3.Show ();相当于相当于a2=operator+(a1)相当于相当于a3=operator+(a1,int)29class incountint c1,c2;public: incount(int a=

22、0,int b=0) c1=a; c2=b; void Show(void)coutc1=c1tc2=c2endl; friend incount operator +(incount &);/前置前置 friend incount operator +(incount &,int);/后置后置;incount operator+(incount &c)c.c1+; c.c2+; return c;incount operator +(incount &c,int)incount cc;cc=c;c.c1+; c.c2+; return cc;void main(void)incount ic

23、1(10,20),ic2(100,200), ic3 , ic4;ic1.Show ();ic2.Show ();ic3=+ic1;/ic3=operator(ic1)ic4=ic2+;/ic4=operator(ic2,n)ic3.Show ();ic4.Show ();30class ThreeDfloat x,y,z;public: ThreeD(float a=0,float b=0, float c=0)x=a;y=b;z=c;friend ThreeD & operator +(ThreeD &);/前置前置friend ThreeD operator +(ThreeD & ,in

24、t);/后置后置void Show()cout x=xty=ytz=zn;ThreeD & operator +(ThreeD & t)t.x+;t.y+;t.z+;return t;ThreeD operator +(ThreeD &t ,int )ThreeD temp=t;t.x+;t.y+;t.z+;return temp;void main(void )ThreeD m1(25,50, 100),m2(1,2,3),m3;m1.Show();m3=+m1;m1.Show();m3.Show();m3=m2+;m2.Show();m3.Show();31 对双目运算符,重载为成员函数时

25、,仅一个对双目运算符,重载为成员函数时,仅一个参数,另一个被隐含;重载为友元函数时,有两参数,另一个被隐含;重载为友元函数时,有两个参数,没有隐含参数。个参数,没有隐含参数。 一般来说,单目运算符最好被重载为成员函一般来说,单目运算符最好被重载为成员函数;对双目运算符最好被重载友元函数。数;对双目运算符最好被重载友元函数。32转换函数转换函数转换函数就是在类中定义一个成员函数,其作用是转换函数就是在类中定义一个成员函数,其作用是将类转换为某种数据类型将类转换为某种数据类型。class A float x, y; public: A(float a, float b) x=a; y=b; ;vo

26、id main(void) A a(2,3); coutaendl;错误!类的对象不能直接输出错误!类的对象不能直接输出利用转换函数将利用转换函数将类类A的对象的对象a转换转换成某种数据类型成某种数据类型Afloat33A : operator float ( ) return x+y; Afloat格式为:格式为:ClassName : operator ( ).类名类名具体的转换算法具体的转换算法欲转换类型欲转换类型关键字关键字转换算法自己定义转换算法自己定义1. 转换函数必须是类转换函数必须是类的成员函数。的成员函数。2. 转换函数的调用是转换函数的调用是隐含的,没有参数。隐含的,没有参

27、数。34class Aint i;public:public:A(int a=0) i=a; void Show(void)couti=iendl; operator int( ) returni;void main(void)A a1(10),a2(20);couta1endl;couta2endl;35class Complexfloat Real,Image;public: Complex(float real=0,float image=0)Real=real;Image=image; void Show(void) coutReal=RealtImage=Imagefloat;Com

28、plex:operator float ()return Real*Real+Image*Image;void main(void)Complex c(10,20);c.Show ();coutcendl;/可以直接输出可以直接输出c,因为已经进行类型转换,因为已经进行类型转换36注注意意,转转换换函函数数只只能能是是成成员员函函数数,不不能能是是友友元元函函数数。转转换换函函数数的的操操作作数数是是对对象象。转转换换函函数数可可以以被被派派生生类类继继承承,也也可可以以被被说说明明为为虚虚函函数。数。37赋值运算符与赋值运算符重载赋值运算符与赋值运算符重载 “”同类型的对象间可以相互赋值,等

29、同于对象的各个同类型的对象间可以相互赋值,等同于对象的各个成员的一一赋值。成员的一一赋值。A a(2,3), b;A a(2,3), b;b ba;a; 但当对象的成员中使用了动态的数据类型时但当对象的成员中使用了动态的数据类型时(用用new开辟空间),就不能直接相互赋值,否则在程开辟空间),就不能直接相互赋值,否则在程序的执行期间会出现运行错误序的执行期间会出现运行错误。38class Achar *ps;public:A( ) ps=0;A(char *s )ps =new char strlen(s)+1; strcpy(ps,s);A( ) if (ps) delete ps;void

30、 Show(void) coutpsendl;void main(void ) A s1(China!),s2(Computer!); s1.Show(); s2.Show(); s2=s1; s1.Show(); s2.Show();/相当于相当于 s2.ps=s1.ps;s1 ps“China”s2 psComputers2.ps=s1.ps首先析构首先析构s2接着析构接着析构s1出错出错39这时,利用编译系统的默认赋值无法正确运行程序,这时,利用编译系统的默认赋值无法正确运行程序,必须重载赋值运算符必须重载赋值运算符“”,即,即重新定义重新定义“”。格式为:格式为: :operator=

31、()赋值运算符必须重载为成员函数。赋值运算符必须重载为成员函数。A A: operator = (A &a)函数返回值类型函数返回值类型成员函数作用域成员函数作用域函数名函数名函数参数函数参数b=a;b.operator=(a);左操作符调左操作符调用右操作符用右操作符40class Sampleint x;public: Sample(int i=0)x=i;void disp(void) cout“x=“xendl;void operator=(Sample &p) x=p.x; ;void main(void) Sample A(20),B; Sample C(A);/使用缺省的拷贝构造

32、函数使用缺省的拷贝构造函数 B=A;/使用赋值运算符重载使用赋值运算符重载 B.disp(); A.disp();41class Achar *ps;public:A( ) ps=0;A(char *s )ps =new char strlen(s)+1; strcpy(ps,s);A( ) if (ps) delete ps;void Show(void) coutpsendl;A& operator=(A &b);void main(void ) A s1(China!),s2(Computer!); s1.Show(); s2.Show(); s2=s1; s1.Show(); s2.S

33、how();必须重新定义必须重新定义“=”42A &A:operator = ( A &b)/重载赋值运算符重载赋值运算符 if ( ps ) delete ps; if ( b.ps) ps = new char strlen(b.ps)+1;strcpy( ps, b.ps); else ps =0; return *this;s1 ps“China”s2 ps“Computer”s2=s1;s2.operator=(s1);“China”返回同种类型的引用适合于连等。返回同种类型的引用适合于连等。s3=s2=s1;43class Achar *ps;public: A( ) ps=0;A

34、(char *s )ps =new char strlen(s)+1;strcpy(ps,s);A( ) if (ps) delete ps;char *GetS( ) return ps;A & operator = ( A &b);/重载赋值运算符重载赋值运算符;A &A:operator = ( A &b)/重载赋值运算符重载赋值运算符 if ( ps ) delete ps; if ( b.ps) ps = new char strlen(b.ps)+1;strcpy( ps, b.ps); else ps =0; return *this;void main(void )A s1(C

35、hina!),s2(Computer!);s2=s1;cout s1= s1.GetS()t;cout s2= s2.GetS()n;s2.ps重新开辟内存,存放重新开辟内存,存放“China”重新开辟内存重新开辟内存44一个字符串类一个字符串类在在C+中中,系系统统提提供供的的字字符符串串处处理理能能力力比比较较弱弱,都都是是通通过过字字符符处处理理函函数数来来实实现现的的,并并且且不不能能直直接接对对字字符符串串进进行行加加法法、减减法法,字字符符串串的的拼拼接接,字字符符串串之之间间的的相相互互赋赋值值等等操操作作。可可以以通通过过应应用用C+提提供供的的运运算算符符重重载载机机制制,可

36、可以以提提供供字字符符串串的的直直接接操操作作能能力力,使使得得字字符符串串的操作与一般的数据一样方便。的操作与一般的数据一样方便。45class String int Length;/字符串长度字符串长度 char *Sp; /字符串在内存中的首地址字符串在内存中的首地址 public: .可见,字符串类只定义了指针,并没有开辟具体的可见,字符串类只定义了指针,并没有开辟具体的空间以存放字符串的内容,所以,无论是构造、析空间以存放字符串的内容,所以,无论是构造、析构还是加减等,构还是加减等,均需要考虑动态开辟空间的问题均需要考虑动态开辟空间的问题,这也是字符串类的难点。这也是字符串类的难点。

37、46class Stringint Length;/字符串的长度字符串的长度 char *Sp;/指向字符串的指针指向字符串的指针public: String()Sp=0;Length=0;/缺省的构造函数缺省的构造函数String( char *s)/以一个字符串常量作为参数以一个字符串常量作为参数Length = strlen(s);Sp=new charLength+1;strcpy(Sp,s);String() if(Sp) delete Sp; friend String operator +(String &,String &);/友元函数重载友元函数重载String & oper

38、ator =(String &);/成员函数重载赋值成员函数重载赋值 String (String &s); /拷贝的构造函数拷贝的构造函数(必须有必须有);void main(void)String str1(China);String str2(CCTV);String str3;str3=str1+str2;str2=str1;coutstr3endl;47String & String: operator =(String &str)if (Sp)delete Sp;Length=str.Length ;Sp =new charLength +1;strcpy(Sp,str.Sp);r

39、eturn *this;String operator +(String &str1,String &str2)String str;str.Length=str1.Length+str2.Length;str.Sp=new charstr.Length +1;strcpy(str.Sp,str1.Sp);strcat(str.Sp,str2.Sp);return str;重新定义字符串赋值重新定义字符串赋值B=A重新定义字符串连接重新定义字符串连接C=A+B48若不定义字符串的析构函数,则可以不若不定义字符串的析构函数,则可以不定义它的拷贝的构造及赋值函数,若定定义它的拷贝的构造及赋值函数,若定义了析构函数,义了析构函数,必须重新定义这两个成必须重新定义这两个成员函数。员函数。原则:每个对象都有自己的独立空间。原则:每个对象都有自己的独立空间。49

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号