什么是运算符的重载? 运算符与类结合,产生新的含义。 为什么要引入运算符重载? 作用:为了实现类的多态性(多态是指一个函数名有多种含义) 怎么实现运算符的重载? 方式:类的成员函数 或 友元函数(类外的普通函数) 规则:不能重载的运算符有 . 和 .* 和 ?: 和 :: 和 sizeof 友元函数和成员函数的使用场合:一般情况下,建议一元运算符使用成员函数,二元运算符使用友元函数 1、运算符的操作需要修改类对象的状态,则使用成员函数。如需要做左值操作数的运算符(如=,+=,++) 2、运算时,有数和对象的混合运算时,必须使用友元 3、二元运算符中,第一个操作数为非对象时,必须使用友元函数。如输入输出运算符<<和>> 具体规则如下:
2. 参数和返回值 当参数不会被改变,一般按const引用来传递(若是使用成员函数重载,函数也为const). 对于返回数值的决定: 1) 如果返回值可能出现在=号左边, 则只能作为左值, 返回非const引用。 2) 如果返回值只能出现在=号右边, 则只需作为右值, 返回const型引用或者const型值。 3) 如果返回值既可能出现在=号左边或者右边, 则其返回值须作为左值, 返回非const引用。 运算符重载举例: +和 -运算符的重载:
调用:
总结: 1、由于+ -都是出现在=号的右边,如c=a+b,即会返回一个右值,可以返回const型值 3、双目运算符的重载: 重载运算符函数名:operator@(参数表) 隐式调用形式:obj1+obj2 显式调用形式:obj1.operator+(OBJ obj2)---成员函数 operator+(OBJ obj1,OBJ obj2)---友元函数 执行时,隐式调用形式和显式调用形式都会调用函数operator+() ++和--运算符的重载:
函数调用:
总结: 1、a++ 函数返回:temp(临时变量) 函数返回是否是const类型:返回是一个拷贝后的临时变量),不能出现在等号的左边(临时变量不能做左值),函数的结果只能做右值,则要返回一个const类型的值 ++a 函数返回:*this; 函数返回是否是const类型:返回原状态的本身,返回值可以做左值,即函数的结果可以做左值,则要返回一个非const类型的值 2、前后缀仅从函数名(operator++)无法区分,只能有参数区分,这里引入一个虚参数int x,x可以是任意整数。 3、单目运算符的重载: 重载运算符函数名:operator@(参数表) 隐式调用形式:obj1@ 或 @obj1 显式调用形式: 成员函数: obj1.operator@( )//前缀 obj1.operator@(0)//后缀 友元函数: operator@(OBJ obj)//前缀 operator@(OBJ obj,int x)//后缀 执行时,隐式调用形式和显式调用形式都会调用函数operator@() 重载下标运算符[ ]
调用:
重载下标运算符[ ]的目的: 1、对象[x] 类似于 数组名[x],更加符合习惯 2、可以对下标越界作出判断 语法: 重载方式:只能使用成员函数重载 函数名:operator[ ](参数表) 参数表:一个参数,且仅有一个参数,该参数设定了下标值,通常为整型,但是也可以为字符串( 看成下标)。 函数调用:显式调用:Obj[arg]-对象[下标] 隐式调用:obj.operator[ ](arg) 返回类型: 1、返回函数引用 + 返回成员的实际类型(由程序员根据函数体定义) 2、因为返回值可以做左值和右值,应该不使用返回值为const类型 但是,为了能访问const对象,下标运算符重载有非const和const两个版本。(待定写) 如:int& Point::operator[](int y)//为什么使用返回引用:返回的值可以做左值,也可以做右值,则必须使用返回引用 重载运算符( )
重载运算符( )的目的: 1、对象( ) 类似于 函数名(x),更加符合习惯 语法: 重载方式:只能使用成员函数重载 重载后还可以继续重载 函数名:operator( )(参数表) 参数表:参数随意,具体根据实际情况而定。 函数调用:显式调用:Obj(x) 隐式调用:obj.operator( )(x) 返回类型: 1、返回成员的实际类型随意,具体由程序员根据函数体定义 2、因为返回值只能做右值,只读,应该使用返回值为const类型
语法: 重载方式:只能使用友元函数重载 且 使用三个引用& 函数名: 输出流: operator<<(参数表) 输入流:operator>>(参数表) 参数表:固定(容易出错啊),两个参数均用引用& 输出流: 必须是两个参数:对输出流ostream& 和 对象 第一个操作数cout,定义在文件iostream中,是标准类类型ostream的对象的引用。 如:ostream& cout,const Point& p 输入流:必须是两个参数:对输入流ostream& 和 对象 第一个操作数是cin,定义在文件iostream,实际上是标准类类型istream的对象的引用 如:instream& cin,const Point& p 函数调用: 输出流: 显式调用:cout<<对象 隐式调用: operator<<(cout,对象) 输入流:显式调用:cin>>对象 隐式调用: operator>>(cin,对象) 返回类型:返回类型固定 + 使用返回函数引用(满足连续输出) 输出流: 返回ostream& 如:ostream& operator<<(ostream& cout,const Point& p) 输入流:返回:istream& 如:istream& operator>>(istream& cin,Point& p) 注意:为什么输入输出操作符的重载必须使用友元函数? 因为:成员函数要求是有对象调用,则第一个参数必须是类的对象,但是<<和>>第一个参数是流的对象引用。 故,不能使用成员函数 |
|
来自: just_person > 《文摘》