第8章 运算符重载.doc_第1页
第8章 运算符重载.doc_第2页
第8章 运算符重载.doc_第3页
第8章 运算符重载.doc_第4页
第8章 运算符重载.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

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

文档简介

第八章 操作符重载重载是C+多态性的体现之一。当定义新的数据类型之后,C+原有操作符提供的操作在语义往往不能满足对新的数据类型的对象进行操作,因此必须对C+原有操作符的操作语义进行扩充,这就是重载的应用需求背景。8.1操作符重载概述当在同一作用域内声明两个或多个相同的名字(即标识符)时,称该名字被重载。在同一作用域内的两个声明,如果声明的名字相同但是数据类型不同,则称这两个声明为重载声明。C+规定,只有函数声明可以被重载,对象声明或类型声明不允许重载。换言之,C+的这一规定将重载严格限制在函数范畴。当重载的函数被调用时,从诸个可调用的重载函数(viable functions)中究竟调用那一个函数则由调用时实参的类型与函数声明时形参的类型相比较结果的一致性决定。这个选择与决定的过程称为重载解析。在C+中,根据函数的定义者是谁可以将函数分为两类。一类是由程序员定义的函数,它们往往被称为用户自定义函数,另一类则是系统提供的函数。就系统提供的函数而言,根据它们的调用方式,又可以进一步分为两类。一类是与用户自定义函数调用方式相同的系统函数,它们往往称为库函数或类库中的成员函数;另一类则沿用自然语言和数学语言的使用习惯,在各类表达式中完成相应的运算,它们往往称为操作符或运算符,但实际上是系统的预定义函数或操作符函数。例如对整型对象x、y,x+y实际表示对预定义函数+的调用。x和y是预定义函数+的参数,但一般习惯上称为+的左操作数和右操作数。由于操作符实际上也是函数,不同的只在于操作符是系统的预定义函数,因此操作符和用户自定义函数一样也可以重载。以加法操作+为例,C+提供的+操作如果不考虑类库支持,则只能进行整数或实数的加法运算,若考虑类库支持则能够进行一般复数的运算。如果用复数来表示电路中的电流和电压,根据电路理论,只有电流和电流才能进行相加减的运算;同理,只有电压和电压才能进行相加减的运算。因此,为了将复数用于电路计算,可以象下面的例子那样设计一个用于电路计算的复数类,并且对加法操作的语义进行扩充。例8-1 设计一个能够用于电路计算的复数类,并重载加法操作。#include iostream.hstruct complexcomplex(double re=0.0,double im=0.0,char ch1=U );complex operator+(complex& c);/声明重载加法操作void show();private:double real,imag;char ch;complex:complex(double re,double im,char ch1 )real=re;imag=im;ch=ch1;coutconstructor is called!endl;complex complex:operator+(complex& c) /定义重载加法操作,扩充加法操作的语义double x,y;if(ch=c.ch)x=real+c.real;y=imag+c.imag;return complex(x,y,ch);elsecoutcant execute the plus opetating!endl;return complex(0,0,U);void complex:show()coutch=0)coutreal+imagiendl;elsecoutrealimagi。在表达式ab中,下标操作符函数operator的右操作数出现在表8-1 C+中可被重载的操作符+*/%&|!=+=*=/=%=&=|=!=&|+-,*()newdeletenewdelete的中间,与传统操作符+、-、*、/操作数分居两侧有所不同。操作符与函数调用符之间的关系如表8-2所示,其中表示某个操作符。单目操作符还有前缀式与后缀式之分。表8-2 操作符与函数调用符之间的关系操作符表达式成员函数表示友员函数表示前缀单目操作符a(a).operator()operator(a)后缀单目操作符a(a).operator(0)operator(a, 0)双目操作符ab(a).operator(b)operator(a, b)赋值操作符=a=b(a).operator=(b)无下标操作符ab(a).operator(b)无类成员访问操作符-a-(a).operator-()无对于操作符重载,有如下需要注意的事项:1 操作符重载不改变操作符原有的优先级和结合性。例如对于算术运算,仍然按照先乘除,后加减的顺序进行运算。又例如,对于辗转赋值:x=y=z,结合性仍然是右结合;即先进行y=z赋值操作,再进行对x的赋值操作。2 操作符重载时不能改变它的操作数的个数,不能有带缺省值的参数。也不能改变操作符使用的语法规则。3 操作符重载是对操作符原有语义的扩充,而不是完全改变操作符的基本语义。例如:从技术上讲,完全可以将+操作符重载之后做减法运算,但是这样做毫无意义。又例如,重载+或-操作符时,仍然应该保持前缀+或-先对操作数自增或自减,然后用自增或自减后操作数的值参与运算;同样,也应该保持后缀+或-先用自增或自减之前操作数的值参与运算,然后再对操作数做自增或自减运算这样一些基本操作语义不变。4 操作符还可以重载为一般函数的形式。即:既非重载为类的成员函数,也不是重载为类的友员函数。此时操作符函数具有全局作用域,并且至少应该有一个类类型的参数。由于每个操作符的操作数是C+语言预先规定好了的,因此进行操作符重载时,参数的个数仍然应该C+语言预先规定设置。操作符重载可以在类中进行,也可以在类外进行。在类外重载的操作符只能访问类中的公有成员。为了使操作符能够访问类中的私有成员,一般将操作符重载为类的成员函数或类的友员函数。如果将操作符重载为类的非静态成员函数,则系统会向其提供this指针,此时操作符函数需要的参数比C+语言预先规定的参数要少一个。因此可以得出如下关于操作符重载时形参个数的规定:1 对单目操作符,当它重载为类的友员函数时,只能声明一个形参;当它重载为类的成员函数时不能再显示声明形参,所需参数由this指针提供。2 对双目操作符,当它重载为类的友员函数时,只能声明两个形参;当它重载为类的成员函数时,只能声明一个形参,该形参是操作符的右操作数,操作符的左操作则由this指针提供。3 如果在类外进行操作符重载,声明形参的个数与将操作符重载为类的友员函数时相同。8.2 操作符重载为类的成员函数操作符重载为类的成员函数声明的一般形式是:T operator操作符(形参表);其中,T是操作符函数的返回值的数据类型。operator是关键字。“operator操作符”称为函数调用符(function-call notation)。形参表中的形参要按照上面规定给出。操作符重载为类的成员函数定义的一般形式是:T 类名:operator操作符(形参表)/函数体现以复数为例讨论操作符的重载问题。复数有代数式(Algebra)与极坐标式(Polar coordinates)之分。复数的代数式适合进行加减运算,而复数的极坐标式则适合进行乘除运算。下面设计一个允许复数的代数式与极坐标式共存的复数类,它允许代数式的复数与极坐标式的复数进行不加转换的运算。每一个复数对象有一个标志成员flag。flag的值为A表示该复数是代数式的复数,若flag的值为P表示该复数是极坐标式的复数。用户在创建了复数对象之后就无须关心它的表现形式而自由的进行四则运算或比较操作。形式转换等操作在复数类的内部自动完成。该复数类规定:加法操作结果的表现形式(即代数式或极坐标式)与左操作数相同;赋值操作后由右操作数的表现形式决定左操作数的表现形式。显示输出函数show在输出极坐标形式的复数时分别输出其模(norm)和幅角(angle),并且幅角在计算时以弧度形式出现,输出时以度的形式出现。数据成员real_norm在代数形式下存放复数的实部,在极坐标形式下存放复数的模;数据成员imag_angle在代数形式下存放复数的虚部,在极坐标形式下存放复数的弧度形式的幅角值。例8-2 能够进行代数式的复数与极坐标式的复数之间的自由四则运算和比较操作的复数类设计及其应用举例。#include iostream.h#include math.hstruct complexcomplex(double re=0.0,double im=0.0,char flag1=A ); /带缺省参数的构造函数complex(complex& rc);/拷贝构造函数complex& operator=(complex& c);/重载赋值操作complex operator+(complex& c); /重载加法操作complex operator*(complex& c); /重载乘法操作int operator=(complex& c); /重载相等比较操作void show();/显示输出函数private:complex polar_to_algebra();/极坐标式到代数式转换函数complex algebra_to_polar();/代数式到极坐标式转换函数double real_norm;/ 实部或模double imag_angle;/虚部或幅角char flag;/ A表示代数式,P表示极坐标式;complex:complex(double re,double im,char flag1 ) /构造函数,缺省时为代数式的复数real_norm=re;imag_angle=im;flag=flag1;complex:complex(complex& rc) /拷贝构造函数real_norm=rc.real_norm;imag_angle=rc.imag_angle;flag=rc.flag; /被初始化复数的表现形式与初值复数对象一致complex& complex:operator=(complex& c)real_norm=c.real_norm;imag_angle=c.imag_angle;flag=c.flag; /被赋值的复数的表现形式与右操作数一致return *this;complex complex:operator+(complex& c)complex t;if(flag=A & c.flag=A) /两者皆为代数式t.real_norm=real_norm+c.real_norm;t.imag_angle=imag_angle+c.imag_angle;if(flag=A & c.flag=P) /this所指复数为代数式t=c.polar_to_algebra(); /引用复数由极坐标式转换为代数式t.real_norm=real_norm+t.real_norm;t.imag_angle=imag_angle+t.imag_angle;if(flag=P & c.flag=A) /this所指复数为极坐标式t=this-polar_to_algebra();/由极坐标式转换为代数式并赋值t.real_norm=c.real_norm+t.real_norm;t.imag_angle=c.imag_angle+t.imag_angle;t=t.algebra_to_polar();/由代数式转换为极坐标式,与左操作数形式一致if(flag=P & c.flag=P) /两者皆为极坐标式complex t1;t1=c.polar_to_algebra();/由极坐标式转换为代数式t=this-polar_to_algebra();/由极坐标式转换为代数式t.real_norm=t1.real_norm+t.real_norm;t.imag_angle=t1.imag_angle+t.imag_angle;t=t.algebra_to_polar();/由代数式转换为极坐标式,与左操作数形式一致return t;complex complex:operator*(complex& c)complex t;if(flag=A & c.flag=A) /两者皆为代数式complex t1;t1=c.algebra_to_polar();/由代数式转换为极坐标式t=this-algebra_to_polar();/由代数式转换为极坐标式t.real_norm=t.real_norm*t1.real_norm;/模相乘t.imag_angle=t.imag_angle+t1.imag_angle;/幅角相加t=t.polar_to_algebra();/由极坐标式转换为代数式,与左操作数形式一致if(flag=A & c.flag=P)t=this-algebra_to_polar();t.real_norm=t.real_norm*c.real_norm;t.imag_angle=t.imag_angle+c.imag_angle;t=t.polar_to_algebra();/由极坐标式转换为代数式,与左操作数形式一if(flag=P & c.flag=A)t=c.algebra_to_polar();t.real_norm=real_norm*t.real_norm;t.imag_angle=imag_angle+t.imag_angle;if(flag=P & c.flag=P)t.real_norm=real_norm*c.real_norm;t.imag_angle=imag_angle+c.imag_angle;t.flag=flag;/ t.flag缺省为A,现必须赋成Preturn t;int complex:operator=(complex& c) /算法:参与比较的两个复数都转换为代数式,并分别赋给t,t1;/然后对t,t1进行比较。相同返回1,不同返回0。complex t,t1;if(flag=A) t=(*this);else t=this-polar_to_algebra();if(c.flag=A) t1=c;else t1=c.polar_to_algebra();if(t.real_norm=t1.real_norm & t.imag_angle=t1.imag_angle)return 1;elsereturn 0;void complex:show()if(flag=A)coutflag=0)coutreal_norm+imag_angleiendl;elsecoutreal_normimag_angleiendl;elsecoutnorm=real_norm angle=imag_angle/3.14159*180endl;complex complex:polar_to_algebra()/由极坐标式转换为代数式的转换函数complex tmp;tmp.imag_angle=real_norm*sin(imag_angle);tmp.real_norm=real_norm*cos(imag_angle);return tmp;complex complex:algebra_to_polar()/由代数式转换为极坐标式的转换函数complex tmp;tmp.real_norm=sqrt(imag_angle*imag_angle+real_norm*real_norm);if(real_norm!=0)tmp.imag_angle=atan(imag_angle/real_norm);elsetmp.imag_angle=3.14159/2;tmp.flag=P;return tmp;void main(void)complex c1(0,0,A),c2(1.5,2.3,A),c3(2.7,-9.2,A);c1=c2+c3; /也可以写成c1=c2.operator+(c3)c1.show();c1=c2*c3; /也可以写成c1=c2.operator*(c3)c1.show();complex c4(0,0,P),c5(10,3.14159/6,P),c6(20,3.14159/6,P);c4=c5.operator+(c6);/也可以写成c4=c5+c6c4.show();c4=c5.operator*(c6);/ 也可以写成c4=c5*c6c4.show();complex c7(0,0,P),c8(1.5,2.3,A),c9(20,3.14159/6,P);c8=c7+c8; /将c8由代数式转换为极坐标式c7=c8+c9;c7.show();c7=c8*c9;c7.show();complex c10(0,0,P),c11(20,3.14159/6,P),c12(1.5,2.3,A);c10=c11+c12;c10.show();c10=c11*c12;c10.show();int x=(c7=c10);coutc7=c10? xendl;程序的运行结果为:A=4.2-6.9i/c1=c2+c3的运算结果A=25.21-7.59i/c1=c2*c3的运算结果norm=30 angle=30 /c4=c5.operator+(c6)的运算结果norm=200 angle=60/c4=c5.operator*(c6)的运算结果norm=22.4834 angle=33.1663/c7=c8+c9的运算结果norm=54.9181 angle=86.8887/c7=c8*c9的运算结果norm=22.4834 angle=33.1663 /c10=c11+c12的运算结果norm=54.9181 angle=86.8887/c10=c11*c12的运算结果c7=c10? 1 / c7=c10的比较结果本例中对复数的加、乘和相等比较操作进行了重载。重载加法操作时算法的基本思想是将复数转换成为代数式之后再进行加法运算,并且返回时复数的表现形式应该按照要求与左操作数的表现形式一致。重载乘法操作时算法的基本思想则是先将复数转换为极坐标式,然后进行乘法操作,当然返回时复数的表现形式也应该与左操作数一样。值得注意的是:在进行诸如c2+c3的加法运算时,调用的是程序中重载的加法操作,而在进行诸如;t.real_norm=real_norm+c.real_norm;的运算时,调用的却是系统提供的两个双精度数之间的加法操作。究竟调用那一个侯选函数,完全要看操作符左、右操作数的数据类型。在重载加法和乘法操作时,程序中先用:complex t;声明一个复数类的局部对象。在返回时,用:return t;返回运算后的结果。这样做的目的是为了严格遵守C+关于加法和乘法操作中不修改左、右操作数的语法规定。另外,在赋值操作operator=(complex& c)函数中,real_norm和imag_angle都是this指针所指的当前对象,也就是左操作数。例如:在c1=c2+c3中,赋值操作的左操作数就是c1。因此,return *this;中,返回的就是c1的值。8.3操作符重载为友员函数操作符重载为类的友员函数声明的一般形式是:friend T operator操作符(形参表);其中,friend 是关键字,它说明该函数是类的友员函数,因此该函数对类成员具有一切存取权限。T是操作符函数的返回值的数据类型。operator是关键字。形参表中的形参应该按照C+语言预先规定的数目给出。操作符重载为类的友员函数定义的一般形式是:T operator操作符(形参表)/函数体除了以operator操作符作为函数调用符之外,定义的形式与一般普通函数相同。关键字friend只能出现在友员函数的声明语句中,在友员函数的定义性声明中不应该出现。下面以IC卡为例设计一个IC_Card类。IC_Card类共有4个数据成员,分别是持卡标识id、持卡人的账号accounts、持卡人的密码password、以及以分为最小整数单位的持卡人的卡内存款余额money。以分为最小整数单位是为了顾及IC卡位编址特性和尽量简化卡内存储操作。同时对充值(加)操作、减值(减)操作进行了重载。由于类中重载的充值操作只允许进行整数充值,所以在类外又对充值操作进行了重载,它允许进行小数操作。四个set操作分别对持卡标识、持卡人的账号、持卡人的密码、以及卡内存款余额进行修改设置。例8-3 设计一个IC类,并且在类中和类外进行操作符的重载。#include iostream.hclass IC_Cardpublic:IC_Card();/缺省构造函数IC_Card(char *id1,char * ac,char * pa,int m);/有参构造函数IC_Card()/析构函数IC_Card& operator=(IC_Card& card);/重载赋值操作friend int operator+(IC_Card& card,int m);/重载充值操作,只允许整数friend int operator-(IC_Card& card,int m);/消费减值操作void show();/显示输出函数void set_accounts(char *ac);/设置持卡人的账号void set_password(char *pa);/设置持卡人的密码void set_money(int sm)money=sm;/设置存款余额char id9;/持卡标识void strcpy(char *s,char *t);/IC_Card类的字符串拷贝函数private:char accounts9;/持卡人的账号char password5;/持卡人的密码int money;/卡内存款余额;void set_id(IC_Card& card,char *pid);/在类外设置持卡标识void operator+(IC_Card& card,double m); /在类外重载充值操作,允许小数IC_Card:IC_Card()strcpy(id,88888888);strcpy(accounts,00000000);strcpy(password,8888);money=0;IC_Card:IC_Card(char *id1,char * ac,char * pa,int m)strcpy(id,id1);strcpy(accounts,ac);strcpy(password,pa);money=100*m;IC_Card& IC_Card:operator=(IC_Card& card)strcpy(id,card.id);strcpy(accounts,card.accounts);strcpy(password,card.password);money=card.money;return *this;void IC_Card:set_accounts(char *ac)strcpy(accounts,ac);void IC_Card:set_password(char *pa)strcpy(password,pa);void IC_Card:strcpy(char *s,char *t)int i=0;while(si = ti)i+;void IC_Card:show()coutid=id accounts=accounts password=password money=(double)money/100endl;int operator+(IC_Card& card,int m)card.money=card.money+100*m;return card.money;int operator-(IC_Card& card,int m)card.money=card.money-100*m;return card.money;void set_id(IC_Card& card,char *pid)card.strcpy(card.id,pid);void operator+(IC_Card& card,double m)int m1=0;m1=card+m1;m1=m1+(int)100*m;card.set_money(m1);void main(void)IC_Card card1,card2(10001234,cs015678,1128,258);card1.show();card2.show();set_id(card1,10009876);card1.set_accounts(cs016666);card1.set_password(3584);card1+123;card1+0.23;card2-58;card1.show();card2.show();程序的运行结果为:id=88888888 accounts=00000000 password=8888 money=0id=10001234 accounts=cs015678 password=1128 money=258id=10009876 accounts=cs016666 password=3584 money=123.23id=10001234 accounts=cs015678 password=1128 money=200friend关键字仅仅出现在友员函数的声明中。由于操作符被重载为类的友员函数,因此加、减操作符都有两个形参,且左操作数是关于IC_Card类对象的引用,右操作数则是整型形参。从money+100*m和money-100*m可以看出,IC_Card类仅仅在其内部才是以分为最小整数单位的,对外仍然按照习惯的元、角、分形式进行处理,从而将以分为最小整数单位的特性封装于IC_Card类的内部。在类外重载的充值操作则允许进行小数充值,其右操作数是double类型的形参;在它的内部,m1=card+m1;中的加法操作调用的是:int operator+(IC_Card& card,int m);函数,在operator+(IC_Card& card,int m)内部card.money=card.money+100*m;语句中的加法操作则是调用系统提供的加法操作。由于类外重载的充值操作不能访问IC_Card类的私有数据成员money,因此在计算出新的余额之后,通过调用set_money操作来完成余额值的更新。本例中,消费减值只能以元为单位进行,读者可以仿照类外重载充值操作自行设计一个类外重载的减值操作。当然,还有其他相应的办法,读者不妨试试。同时,象11+card1的操作在本例中也没有得到支持,作为练习,读者可以自行编制重载左操作数为数值型数据的加法操作。8.4 增量/减量操作符的重载在进行增量操作符+和减量操作符-的重载时,要注意+和-有前缀式与后缀式之分。根据表8-2中关于前缀单目操作符和后缀单目操作符重载为类的成员函数和重载为类的友元函数的规定以及前面讨论的关于单目操作符参数个数的规定。当前缀+和前缀-重载为类的成员函数时,+obj和-obj编译器理解的形式为:obj.operator+() 和obj.operator-() 函数原型为:T operator+(); 和T operator-();其中,T为返回类型。当前缀+和前缀-重载为类的友员函数时,+obj和-obj编译器理解的形式为:operator+(obj) 和operator-(obj) 函数原型为:friend T operator+(U obj); 和friend T operator-(U obj);其中,T为返回类型,U为操作数obj的数据类型。函数定义时不要用friend关键字。同理,当后缀+和后缀-重载为类的成员函数时, obj+和obj-编译器理解的形式为:obj.operator+(0) 和obj.operator-(0)函数原型为:T operator+(int ); 和T operator-(int );其中,T为返回类型。并且,当后缀+和后缀-重载为类的友员函数时, obj+和obj-编译器理解的形式为:operator+(obj,0) 和operator-(obj,0)函数原型为:friend T operator+(U obj,int );和friend T operator-(U obj ,int );其中,T为返回类型,U为操作数obj的数据类型。函数定义时不要用friend关键字。仍然以例8-3的IC_Card为例,扩充增量和减量操作符的重载。将前缀+和前缀-重载为类的成员函数;将后缀+和后缀-重载为类的友元函数。例8-4 扩充IC_Card类,完成前缀+和前缀-,以及后缀+和后缀-的重载。1在IC_Card类的声明中扩充下面声明:IC_Card operator+();IC_Card operator-();friend IC_Card operator+(IC_Card& card,int);friend IC_Card operator-(IC_Card& card,int);2在IC_Card类的实现中扩充下面函数的实现:IC_Card IC_Card:operator+()+money;return *this;IC_Card IC_Card:operator-()-money;return *this;IC_Card operator+(IC_Card& card,int)IC_Card card1=card;card.money+; /与card1.money=card.money+;等价return card1;IC_Card operator-(IC_Card& card,int)IC_Card card1=card;card.money-;/与card1.money=card.money-;等价return card1;3相应的mian函数如下:void main(void)IC_Card card1,card2(10001234,cs015678,1128,258);card1.show();card2.show();set_id(card1,10009876);card1.set_accounts(cs016666);card1.set_password(3584);card1+123;card1+0.23;card2-58;card1.show();card2.show();IC_Card card3,card4;card3=+card1;coutafter card3=+card1, card1 is:endl;card1.show();coutafter card3=+card1, card3 is:endl;card3.show();card4=card1+;coutafter card4=card1+, card1 is:endl;card1.show();coutafter card4=card1+, card4 is:endl;card4.show();程序的运行结果为:id=88888888 accounts=00000000 password=8888 money=0id=10001234 accounts=cs015678 password=1128 money=258id=10009876 accounts=cs016666 password=3584 money=123.23id=10001234 accounts=cs015678 password=1128 money=200after card3=+card1, card1 is:id=10009876 accounts=cs016666 password=3584 money=123.24after card3=+card1, card3 is:id=10009876 accounts=cs016666 password=3584 money=123.24after card4=card1+, card1 is:id=10009876 accounts=cs016666 password=3584 money=123.25after card4=card1+, card4 is:id=10009876 accounts=cs016666 password=3584 money=123.24显然,card3=+card1中的前缀+使card1和card3的money成员的值同为123.24;而card4=card1+中的后缀+使card1的money成员的值为123.25,而card4的money成员的值为123.24,满足后缀+的操作语义。8.5 下标操作符的重载下标操作符是一个双目操作符。它的左操作数是数组名,右操作数是下标。下标操作符只能被重载为类的非静态成员函数。因此只能为下标操作符显式声明一个形参,该形参为下标操作符的右操作数,左操作数则由this指针提供。设在类T中重载下标操作符,则下标操作符重载声明的一般形式为:T1 operator(U );其中,T1是返回值的数据类型,U是形参的数据类型,operator是函数调用符。下标操作符重载定义的一般形式为:T1 T:operator(U )/函数体对下标操作符进行了重载声明和定义之后,就可以采用下面的形式来调用它:ab或:a.operator(b)其中,a是左操作数,相当于数组名。此处所谓的相当是指:数组名是一个常量,而此处的a却不一定是常量;但是a又可以象数组名一样使用。b是下标,它可以是任意类型。如整型、字符型、甚至是某个类类型。例8-5 利用下标操作符重载设计一个能够判断下标越界的双精度型数组并对其进行操作。#include iostream.h#include stdlib.hclass arraypublic: array(int size); array(); double& operator(int i);private:double *a;int up_bound;array:array(int size)up_bound=size;a=new doublesize;array:array()delete a;double& array:operator(int i)if(i=up_bound)coutsubscript overflow!endl;exit(1);return ai;void main(void)array b(10);b0=12.34;b3=b2=b1=b0;b8=567.89;coutb0 b3 b8endl;b10=256.78;程序运行结果为:12.34 12.34 567.89subscript overflow!程序中用到了new和delete操作符,a=new doublesize;语句将先执行new操作,创建一个有size个元素的动态数组,并将该数组的起始地址赋给指针a。析构函数中的delete a;语句的作用是清除(即回收)由new操作创建的动态数组。详细内容请参阅第九章中的“9.10.2 new操作和delete操作”。array b(10);语句创建了一个array类型的对象,指针成员b.a指向有10个元素的double型数组。b0=12.34;语句的执行过程是先计算b0,调用重载过的下标操作符函数。此时实参0传递给形参i,然后判断下标是否越界,如果没有越界,执行return ai;而ai显然是指针成员b.a所指数组中打头的元素a0,由于返回类型是double&,因此计算b0的最终结果是得到关于a0的一个引用。因此b0=12.34就相当于a0=12.34。a0是表达式b0调用重载的下标操作符函数所得到的计算结果这句话是理解下标操作符重载的关键。当执行b10=256.78;语句时,由于下标越界而程序输出提示之后而终止执行。例8-6 通过有上下文语义的下标操作符重载,实现对数

温馨提示

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

评论

0/150

提交评论