由于系统给定的输入<<,输出>>,前置和后置++,--运算符只能处理类似于int,float等系统已经定义好的类型的变量,为了能对我们自己定义的类的对象也能进行这些操作,我们就要重载这些运算符
定义一个复数类的对象:
class Complex
{
public:
Complex(double real = 0, double imag = 0);
private:
//实部
double real;
//虚部
double imag;
};
1.重载输出<<
在类中的public区域加入一个友元函数
friend ostream& operator<<(ostream& out, const Complex&p);//重载输出运算符
在类外定义函数operator<<
/重载输出运算符
//由于要满足cout<<p1<<p2这种操作,所以cout<<p1要返回输出流,才能继续输出p2,所以函数的类型为输出流ostream
ostream& operator<<(ostream& out, const Complex& p)
{
return out << "(" << p.real << "," << p.imag << "i)";
}
首先我们的返回值类型为什么是ostream& 呢:
因为我们要满足cout<<p1<<p2这样的操作,所以在实现cout<<p1后我们的返回值还要能够输出p2,因此我们返回值的类型应该为一个输出流类型,输出流类型即是ostream,返回的内容即是cout<<p1。
我们为什么不直接将函数写在类中而是要写为一个友元函数传入类中呢
因为我们要实现的操作是cout<<p1,其中cout在我们要重载的运算符<<的左边,而p1即类的对象在<<的右边,要是我们将重载的运算符<<的函数写为类的成员函数,将输出流作为函数的参数,这样在调用的时候就变成了p1<<cout,显然这是不符合逻辑的,所以我们重载的运算符<<的操作不能写为类的成员函数
2.重载输入运算符>>
在类中的public区域加入一个友元函数
friend istream& operator>>(istream& in, Complex&p);//重载输出运算符
//重载输入运算符
istream& operator>>(istream& in, Complex& p)
{
cout << "请输入复数的实部" << endl;
in >> p.real;
cout << "请输入复数的虚部" << endl;
in >> p.imag;
return in;
}
重载输入运算符>>和重载输出<<运算符相差不大,只是输入运算符的第一个参数为输入流,函数类型也为输入流
3.重载前置++运算符
Complex& operator++()
{
++(this->real);
return *this;
}
重载前置++运算符就只需要一个对象,所以将函数定义在类中即可,不用传参
由于要满足++(++p)这种操作,所以返回类型为Complex&
4.重载前置--运算符
//重载前置--运算符
//要满足--(--p)这种操作,所以返回类型为Complex&
Complex& operator--()
{
--(this->real);
return *this;
}
和前置++差不多。
5.重载后置++运算符
//重载后置++运算符
//后置++运算符不能有(p++)++这样的操作,所以返回值为const Complex
//里面的参数int是无意义的,这里加上int是为了与上面同名的定义前置++的函数进行区分(因为函数返回类型不能区分重名函数,只有函数参数的类型和数量可以区分)
const Complex operator++(int)
{
//创建一个临时对象来记录实际对象在自增之前的数值
Complex temp = *this;
++(this->real);
return temp;
}
由于后置++运算符不能有(p++)++这样的操作,所以返回值应为不可修改的右值,即类型为const Complex。
而函数的类型也是用于判断是前置++还是后置++的根据,前置++是可修改的左值而后置++是不可修改的右值
我们可以看到在重载后置++运算符的函数中有一个int参数,但我们在程序中并没有用到这个参数,那为什么要写这个参数呢,是因为重载前置++运算符和重载后置++运算符的函数名是相同的,出现了重名的情况,而我们的系统是不能根据函数的类型来区分重名函数的,只能通过参数的个数和类型来区分,所以我们在这里加上一个参数int就只是为了与前面的重名函数相区分
6.重载后置--运算符
//重载后置--运算符
const Complex operator--(int)
{
//创建一个临时对象来记录实际对象在自增之前的数值
Complex temp = *this;
--(this->real);
return temp;
}
重载后置--运算符的要点和重载后置++运算符差不多。