C++当中+,-,*,/等运算符只能对基本类型的常量或变量进行运算,对于自定义类型是不能直接使用的,c++在这里提供了“运算符重载”机制,赋予运算符新的功能,使得自定义类型之间也可以进行简单的运算。
运算符重载是运算符重载函数对运算符进行重载的,函数名有一个固定的模式(operator+运算符);
运算符重载函数:返回类型 operator 运算符(形参列表)。
运算符可以被重载成全局函数,也可以被重载成成员函数。一般更倾向于重载成成员函数。
下面我们举几个简单的例子:
定义一个简单的坐标类,首先我们先来实现赋值运算符=的重载,当我们实例化出来一个对象,接着想把当前对象赋值给一个新的对象。
接着我们来实现+=运算符的重载。
下面是-=运算符的重载。
实现*=运算符的重载。
除了加,减,乘以外,我们自定义类型当中并没有输入输出,在这里我们还应该实现输入输出运算符的重载使坐标类使用起来更加方便。
在输入输出运算符重载时我们要注意一个问题:
第一点:上面我们所重载的运算符函数看似只有一个参数但是它们都是成员函数,成员函数会有一个默认参数this指针,所以说上面运算符重载函数都是有两个形参第一个是this指针,第二个才是我们所定义的形参。
第二点:同时我们在使用重载运算符时,运算符的左边是第一个参数,运算符的右边是第二个参数。这使得我们按上面成员函数的方式重载输入输出运算符时会出现下面这种情况。
这里可以正常定义,但是我们在使用时就会出现错误,
我们正常使用时会报错,这里是为什么?
我们再看上面提到的第二点得知我们应该这样使用输出运算符。
左边为我们要输出的对象右边为输出运算符,这样显然不符合我们想要的结果,所以说我们不能将输入输出运算符在类当中以成员函数的方式重载,而是应该在类外定义将第一个参数设为运算符,我们又如何能让类外函数访问到类内的成员变量,这里我们可以使用友元函数。
我们在类外定义成全局函数,同时在类内声明为友元函数就可以实现运算符的正常使用。
代码部分:
#include<iostream>
using namespace std;
class coordinate//坐标类默认坐标(0,0)
{
public:
coordinate(int x=0, int y=0)//全缺省的构造函数
{
_x = x;
_y = y;
}
coordinate& operator=(const coordinate& L)
{//重载=使得obj=obj能够成立
_x = L._x;
_y = L._y;
//注意:这里并未动态分配空间
//所以无需考虑深浅拷贝问题
return *this;//返回值类型为类类型的引用可以减少拷贝次数,同时实现连续赋值。
}
void operator+=(const coordinate& L )
{//重载+=运算符实现obj+=obj
_x = _x + L._x;
_y = _y + L._y;
}
void operator-=(const coordinate& L)
{//重载-=运算符实现obj-=obj
_x = _x - L._x;
_y = _y - L._y;
}
void operator*=(const coordinate& L)
{//重载*=运算符实现obj*=obj
_x = _x * L._x;
_y = _y * L._y;
}
//定义友元函数实现输入输出运算符的重载
friend ostream& operator<<(ostream& out, const coordinate& L);
friend istream& operator>>(istream& in, coordinate& L);
private:
int _x;//x轴坐标
int _y;//y轴坐标
};
ostream& operator<<(ostream& out, const coordinate& L)
{
return out << "("<<L._x<<","<< L._y<<")";
}
istream& operator>>(istream& in, coordinate& L)
{
cout << "请输入x的值:";
in >> L._x;
cout << "请输入y的值:";
in >> L._y;
return in;
}
int main()
{
coordinate A(1,2);
coordinate B;
coordinate C;
B =C= A;//连续赋值
C += B;
cout <<"A的坐标为:" << A << endl;//输出A的坐标
cout << "B的坐标为:" << B << endl;//输出B的坐标
cout << "C的坐标为:" << C << endl;//输出C的坐标
cin >>A;//对A对象进行更改
cout << "更改后A的坐标为:" << A << endl;//输出A的坐标
return 0;
}