operator重载运算符
Posted 芬乐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了operator重载运算符相关的知识,希望对你有一定的参考价值。
1.重载运算符的函数一般格式如下
函数类型 operator 运算符名称 (形参表列)
{对运算符的重载处理}
例如,想将“+”用于Complex(复数)的加法运算,函数的原型可以是这样的:
Complex operator + (Complex & c1,Complex &c2);
operator+函数表示对运算符+重载。
其中,operator是关键字,专门用于定义重载运算符的函数的,运算符名称就是C++提供给用户的预定运算符。
注意:函数名是由operator和运算符组成。
2.两个形参是Complex类对象的引用,要求实参为Complex类对象。
- 在执行Point类型相加的表达式a+b时,系统就会自动调用operator+函数,把a+b作为实参,与形参进行虚实结合。
- 下面的a+b语句中,相当于a调用函数+,把b作为该函数的一个参数传递给该函数,从而实现了两个Point类型的相加。
- 为了说明把运算符重载后,执行表达式就是调用函数的过程,可以把两个整数相加也想象称为调用下面的函数:
实参和形参匹配才可以调用函数。
#include <iostream> using namespace std; struct Point { int x, y; Point(int x = 0, int y=0):x(x),y(y){} }; Point operator + (const Point& A, const Point& B) { return Point(A.x+B.x, A.y+B.y); } ostream& operator << (ostream &out, const Point&p) { out << "(" << p.x << "," << p.y << ")"; return out; } int main() { Point a, b(1, 2); a.x = 3; cout << a + b <<"\n"; system("pause"); return 0; }
操作符重载实现为非类成员函数(全局函数)
对于全局重载操作符,代表左操作数的参数必须被显式指定。
****
运算符重载函数operator +还可以改写的更简练一些:
Complex Complex::operator+(Complex &c2)
{
return Complex(c2.real+real,c2.imag+imag);
}
return语句中的Complex(c2.real+real,c2.imag+imag)是建立一个临时对象,它没有对象名,是一个无名对象。
在建立临时对象过程中,调用构造函数。return语句将此临时对象作为函数返回值。
那么,我们将+运算符进行了重载以后,可否将一个常量和一个复数相加呢?比如:
c3=3+c2; //错误,与形参类型不匹配
实参和形参匹配才可以调用函数。
应写成对象形式,如:
c3=Complex(3,0)+c2; //正确,类型均为对象
还需要说明的是:运算符被重载后,其原有的功能仍然保留,没有丧失或改变。
例如,运算符+被重载以后,仍然可以用于int,float,double,char类型数据的运算,同时又增加了用于定义时数据类型的相加的功能。
编译系统根据表达式的上下文,即根据运算符两侧(如果是单目运算符则为一侧)的数据类型决定的。
如,对于3+5,则执行整数加法;对于3.4+5.45,则执行双精度数加法;对于两个复数类相加,则执行复数加法。
3.如何决定把一个操作符重载为类成员函数还是全局名字空间的成员呢?
①如果一个重载操作符是类成员,那么只有当与他一起使用的左操作数是该类的对象时,该操作符才会被调用。如果该操作符的左操作数必须是其他的类型,则操作符必须被重载为全局名字空间的成员。
②C++要求赋值=,下标[],调用(), 和成员指向->操作符必须被定义为类成员操作符。任何把这些操作符定义为名字空间成员的定义都会被标记为编译时刻错误。
③如果有一个操作数是类类型如string类的情形那么对于对称操作符比如等于操作符最好定义为全局名字空间成员。
以上是关于operator重载运算符的主要内容,如果未能解决你的问题,请参考以下文章
void()、逗号运算符 (operator,) 和不可能的 (?) 重载