第11章77运算符重载.

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第11章运算符重载什么是运算符重载运算符重载的方法几个特殊的运算符的重载自定义类型转换运算符运算符重载实例什么是运算符重载使系统内置的运算符可以用于类类型例如:+运算符能够实现2个对象间的加。例如:类A的对象a1、a2、a3,希望:a3=a1+a2;即:分别把对象a1和a2的各个数据成员值对应相加,然后赋给对象a3。问题的提出把某些事交给系统去做,用户只要知道相加就可扩充运算符的功能增强了C++语言的可扩充性使用户定义的类更像系统的内置类型运算符重载的限制不是所有的运算符都能重载重载不能改变运算符的优先级和结合性重载不能改变运算符的操作数个数不能创建新的运算符可以重载的运算符+-*/%^&|~!=+=-=*=/=%=^=&=|=====!===&&||++---*,-[]()newdeletenew[]delete[]不能重载的运算符..*::?:sizeof第11章运算符重载什么是运算符重载运算符重载的方法几个特殊的运算符的重载自定义类型转换运算符运算符重载实例运算符重载的方法运算符重载就是写一个函数解释某个运算符在某个类中的含义要使得系统能自动找到重载的这个函数,函数名必须要体现出和某个被重载的运算符的联系。C++中规定,重载函数名为operator@其中,@为要重载的运算符。如要重载“+”运算符,该重载函数名为operator+。要重载赋值运算符,函数名为operator=。函数原型运算符的重载不能改变运算符的运算对象数。因此,重载函数的形式参数个数(包括成员函数的隐式指针this)与运算符的运算对象数相同运算符重载可以重载成成员函数也可以重载成全局函数实现。重载成全局函数时,最好把此函数设为友员函数如果作为类的成员函数,它的形式参数个数比运算符的运算对象数少1。这是因为成员函数有一个隐含的参数this。在C++中,把隐含参数this作为运算符的第一个参数。当把一个一元运算符重载成成员函数时,该函数没有形式参数。把一个二元运算符重载成成员函数时,该函数只有一个形式参数,就是右操作数,当前对象是左操作数。重载实例为rational类增加“+”和“*”以及比较的重载函数,用以替换现有的add和multi函数方案一:重载成成员函数classRational{private:intnum;intden;voidReductFraction();public:Rational(intn=0,intd=1){num=n;den=d;}Rationaloperator+(constRational&r1)const;Rationaloperator*(constRational&r1)const;booloperator(constRational&r1)const;booloperator==(constRational&r1)const;booloperator(constRational&r1)const;booloperator=(constRational&r1)const;booloperator=(constRational&r1)const;booloperator!=(constRational&r1)const;voiddisplay(){coutnum'/'den;}}函数实现RationalRational::operator+(constRational&r1)const{Rationaltmp;tmp.num=num*r1.den+r1.num*den;tmp.den=den*r1.den;tmp.ReductFraction();returntmp;}RationalRational::operator*(constRational&r1)const{Rationaltmp;tmp.num=num*r1.num;tmp.den=den*r1.den;tmp.ReductFraction();returntmp;}boolRational::operator(constRational&r1)const{returnnum*r1.denden*r1.num;}boolRational::operator==(constRational&r1)const{returnnum==r1.num&&den==r1.den;}boolRational::operator(constRational&r1)const{returnnum*r1.denden*r1.num;}boolRational::operator=(constRational&r1)const{returnnum*r1.den=den*r1.num;}boolRational::operator=(constRational&r1)const{returnnum*r1.den=den*r1.num;}boolRational::operator!=(constRational&r1)const{return!(*this==r1);}方案二:重载成友员函数classRational{friendRationaloperator+(constRational&r1,constRational&r2);friendRationaloperator*(constRational&r1,constRational&r2);friendbooloperator(constRational&r1,constRational&r2);friendbooloperator==(constRational&r1,constRational&r2);friendbooloperator(constRational&r1,constRational&r2);friendbooloperator=(constRational&r1,constRational&r2);friendbooloperator=(constRational&r1,constRational&r2);friendbooloperator!=(constRational&r1,constRational&r2);private:intnum;intden;voidReductFraction();public:Rational(intn=0,intd=1){num=n;den=d;}voiddisplay(){coutnum'/'den;}};函数的实现Rationaloperator+(constRational&r1,constRational&r2){Rationaltmp;tmp.num=r1.num*r2.den+r2.num*r1.den;tmp.den=r1.den*r2.den;tmp.ReductFraction();returntmp;}Rationaloperator*(constRational&r1,constRational&r2){Rationaltmp;tmp.num=r1.num*r2.num;tmp.den=r1.den*r2.den;tmp.ReductFraction();returntmp;}其他函数实现略重载后有理数类的使用intmain(){Rationalr1(1,6),r2(1,6),r3;r3=r1+r2;r1.display();cout+;r2.display();cout=;r3.display();coutendl;r3=r1*r2;r1.display();cout*;r2.display();cout=;r3.display();coutendl;return0;}全局函数vs成员函数大多数运算符都可以重载成成员函数或全局函数。赋值(=)、下标([])函数调用(())和成员访问(-)必须重载成成员函数。具有赋值意义的运算符,如复合的赋值运算符以及++和--,不一定非要定义为成员函数,但最好定义为成员函数。具有两个运算对象的运算符最好重载为全局函数,这样可以使得应用更加灵活。如果把加运算定义成全局函数,r是有理数类的对象,则2+r是一个合法的表达式。第11章运算符重载什么是运算符重载运算符重载的方法几个特殊的运算符的重载自定义类型转换运算符运算符重载实例几个特殊的运算符的重载赋值运算符下标运算符函数调用运算符++和—运算符的重载重载函数的原型设计考虑输入输出运算符重载赋值运算符对任一类,如果用户没有自定义赋值运算符函数,那么系统为其生成一个缺省的赋值运算符函数,在对应的数据成员间赋值。一般情况下,这个缺省的赋值运算符重载函数能满足用户的需求。但是,当类含有类型为指针的数据成员时,可能会带来一些麻烦。对DoubleArray类对象执行array1=array2的问题会引起内存泄漏使这两个数组的元素存放于同一块空间中当这两个对象析构时,先析构的对象会释放存储数组元素的空间。而当后一个对象析构时,无法释放存放数组元素的空间赋值运算符“=”的原型赋值运算符只能重载成成员函数函数原型:X&X::operator=(constX&source){//赋值过程}一旦创建了对象x1,x2,可以用x1=x2赋值。DoubleArray类的赋值运算符重载函数DoubleArray&DoubleArray::operator=(constDoubleArray&right){if(this==&right)return*this;delete[]storage;low=right.low;high=right.high;storage=newdouble[high-low+1];for(inti=0;i=high-low;++i)storage[i]=right.storage[i];//复制数组元素return*this;}赋值运算符重载要点一般来讲,需要自定义拷贝构造函数的类也需要自定义赋值运算符重载函数。在赋值运算符重载函数中,已经将参数的值赋值给了当前对象,那为什么还需要返回值呢?记住,在C++中,赋值是一个运算,它可以形成一个表达式,而该表达式的结果值就是赋给左边的对象的值。因此,赋值运算符重载函数必须返回赋给左边的对象值。赋值运算符重载和拷贝构造函数一般来讲,需要拷贝构造函数的类也需要重载赋值运算符定义对象时给对象赋初值调用的是拷贝构造函数程序的语句部分中的赋值语句调用的是赋值运算符重载函数几个特殊的运算符的重载赋值运算符下标运算符函数调用运算符++和—运算符的重载重载函数的原型设计考虑输入输出运算符重载下标运算符重载能否象普通的数组那样通过下标运算操作DoubleArray类的对象,这样可以使DoubleArray类更像一个功能内置的数组。可以通过重载下标运算符([])来实现下标运算符是二元运算符,第一个运算数是数组名,第二个运算数是下标值下标运算符必须重载成成员函数DoubleArray类的[]重载double&DoubleArray::operator[](intindex){if(indexlow||indexhigh){cout下标越界;exit(-1);}returnstorage[index-low];}DoubleArray类的使用定义:DoubleArrayarray(20,30);数组输入:for(i=20;i=30;++i){cout请输入第i个元素:;cinarray[i];}数组输出:for(i=20;i=30;++i)coutarray[i]'\t';几个特殊的运算符的重载赋值运算符下标运算符函数调用运算符++和—运算符的重载重载函数的原型设计考虑输入输出运算符重载函数调用运算符函数调用运算符()是一个二元运

1 / 77
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功