您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 面向对象程序设计第十五讲
注意事项运算符重载函数operator@()可以返回任何类型,甚至可以使void类型,但通常返回类型与它所操作的类的类型相同,这样可使重载运算符用在复杂的表达式中。例如:复数的连续加、减。在重载运算符时,运算符函数所作的操作不一定要保持C++中该运算符原有的含义,但这样容易造成混乱。所以保持原含义,容易被接受,也符合人们的习惯。在C++中,用户不能定义新的运算符,只能从C++已有的运算符中选择一个恰当的运算符重载。C++编译器根据参数的个数和类型来决定调用哪个重载函数。因此,可以为同一个运算符定义几个运算符重载函数来进行不同的操作。运算符重载属于静态联编友元运算符重载在C++中,可以把运算符函数定义成某个类的友元函数,称为友元运算符函数。友元运算符函数在类的内部的声明格式:friendtypeoperator@(参数表);定义格式:typeoperator@(参数表){//函数体}与成元运算符不同,友元运算符函数是不属于任何类对象的,它没有this指针。若重载的是双目运算符,则参数表中有两个操作数;若重载的是单目运算符,则参数表中只有一个操作数运算符重载为类的友元函数,就可以自由地访问该类的任何数据成员。这时,运算所需要的操作数都需要通过函数的形参来传递,在参数表中形参从左到右的顺序就是运算符操作数的顺序。友元函数的双目运算符重载对于双目运算符B,如果它的一个操作数为A类的对象,就可以将B重载为A类的友元函数,该函数有两个形参,其中一个形参的类型是A类。重载后的使用方式:aa@bb;operator@(aa,bb);例子#includeiostream.hclasscomplex{public:complex(doubler=0.0,doublei=0.0){real=r;imag=i;}friendcomplexoperator+(complexc1,complexc2);friendcomplexoperator-(complexc1,complexc2);voiddisplay();private:doublereal;doubleimag;};voidcomplex::display(){coutreal.imagendl;}complexoperator+(complexc1,complexc2){returncomplex(c2.real+c1.real,c2.imag+c1.imag);}complexoperator-(complexc1,complexc2){returncomplex(c1.real-c2.real,c1.imag-c2.imag);}voidmain(){complexc1(5,4),c2(2,10),c3;c1.display();c2.display();c3=c1+c2;c3.display();c3=c1-c2;c3.display();}友元函数的单目运算符重载对于前置单目运算符U,如果要实现表达式Uoprd,其中oprd为A类的对象,则U可以重载为A类的友元函数,函数的形参为A类的对象oprd。对于后置单目运算符“++”和“—”,如果要实现表达式oprd++或oprd--,其中oprd为A类的对象,那么运算符就可以重载为A类的友元函数,这时函数的形参有两个,一个是A类的对象oprd,另一个是整型(int)形参。成员运算符函数与友元运算符函数的比较对双目运算符而言,成员运算符函数带有一个参数,而友元运算符函数带有两个参数;对单目运算符而言,成员运算符不带参数,而友元运算符函数带一个参数。双目运算符一般可以被重载为友元运算符函数或成员运算符函数,但有些情况,必须使用友元函数。nclassnclass::operator+(intx){nclasstemp;temp.a=a+x;temp.b=b+x;returntemp;}nclassob;ob=ob+100;ob=100+ob;(error,?如何实现?)成员运算符函数和友元运算符都可以用习惯方式调用,也可以用他们专用的方式调用。习惯形式友元运算符函数调用形式成员运算符函数调用形式a+boperator+(a,b)a.operator+(b)-aoperator-(a)a.operator-()a++operator++(a,0)a.operator++(0)C++的大部分运算符即可说明为成员运算符,又可说明为友元运算符函数,究竟选择哪一种运算符函数好一些,没有定论,这主要取决于实际情况和程序员的习惯。一般而言,对于双目运算符,将它重载为一个友元运算符函数比重载为一个成员运算符函数便于使用。若一个运算符的操作需要修改类对象的状态,则选择成员运算符函数较好。如果运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则运算符重载必须有友元函数,而不能用成员函数。赋值运算符“=”的重载对任一类X,如果没有用户自定义的赋值运算符函数,那么系统将自动地为其生成一个缺省的赋值运算符函数,例如:X&X::operator=(constx&source){//成员间赋值}通常,缺省的赋值运算符函数是能够胜任工作的,但在某些特殊情况下,如类中有指针类型时,使用缺省的赋值运算符会产生错误。classstring{public:string(char*s){ptr=newchar[strlen(s)+1];strcpy(ptr,s);}~string(){deleteptr;}voidprint(){coutptrendl;}private:char*ptr;}stringp1(“chen”);stringp2=p1;动态空间p1ptrp2ptrstring&string::operator=(conststring&s){if(this=&s)return*this;deletestr;ptr=newchar[strlen(s.ptr)+1];strcpy(ptr,s.ptr);return*this;}类的赋值运算符“=”只能重载为成员函数,不能重载为友元函数。类的赋值运算符“=”可以被重载,但重载了运算符函数operator=()不能被继承。类型转换运算符系统预定义类型间的转换类型转换是将一种类型的值转换为另一种类型值。对于系统预定义的类型,C++提供两种类型转换,一种是隐式类型转换(标准类型转换),另一种是显式类型转换。类类型与系统预定义类型间的转换通过构造函数进行类型转换(p325)通过类型转换函数进行类型转换类类型转换函数可以用来把用户定义的类类型转换成基本类型。他是一种类似显式类型转换的机制。在类中,类型转换函数定义的一般个市为:classX{//…operatortype(){//…returntype类型的数据;}//…};转向的目标类型(通常为基本类型)功能:将类X的对象转换为类型为type的数据classcomplex{private:floatreal,imag;public:complex(floatr=0,floati=0){real=r;imag=i;}operatorfloat(){couttypechangedtofloat...\n;returnreal;}operatorint(){couttypechangedtoint...\n;returnint(real);}};注意事项类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。类型转换函数与普通的成员函数一样,也可以在类定义体中声明函数原型,而将函数体定义在类外部。在一个类中可以定义多个类型转换函数。C++编译器将根据操作数的类型自动地选择一个合适的类型转换函数与之匹配。当在可能出现二义性的情况下,应显式地使用类型转换函数进行类型转换。
本文标题:面向对象程序设计第十五讲
链接地址:https://www.777doc.com/doc-3261664 .html