二元运算符重载

(1)加号 + 的重载

加号 + 的重载方式有两种:一种是友元函数重载,一种是成员函数重载。

1)先来看成员函数重载,如下:

定义一个坐标类:Coordinate

class Coordinate
{
    public:
      Coordinate(int x, int y);
      Coordinate operator+(const Coordinate &coor);
    private:
      int m_iX;
      int m_iY;
}

在类中声明成员函数 operator+(),它的参数是 const Coordinate &coor

在实现时:

Coordinate operator+(const Coordinate &coor)
{
    Coordinate temp;
    temp.
}

首先需要定义一个临时对象 temp,传入对象 coor 的 m_iX 要和

当前对象的 m_iX 相加,赋值给临时对象 temp 的 m_iX,而对于

m_iY 同理 … 最后将 temp 作为返回值返回出去。

在使用时:

int main(void)
{
    Coordinate coor1(3,5);
    Coordinate coor2(4,7);
    Coordinate coor3(0,0);
    coor3=coor1+coor2;//coor1.operator+(coor2)
    return 0;
}

定义 3 个 Coordinate 的对象 coor1、coor2、coor3,用 coor3 来

接收 coor1 与 coor2 相加的和,这里的加号 + 就已经用到了运算符

重载,相当于 coor1.operator+(coor2)。

注意:在加号 + 的重载函数 operator+() 的传入参数 coor2 的前面,

其实有一个隐形参数 this,而 this 就相当于传入的第一个参数 coor1。

2)再来看友元函数重载,如下:

class Coordinate
{
    friend Coordinate operator+(const Coordinate &c1,const Coordinate &c2);
    public:
      Coordinate(int x, int y);
    private:
      int m_iX;
      int m_iY;
}

友元函数重载相对于成员函数重载来说,更能说明问题:

通过 friend 声明将全局函数 operator+() 声明为友元函数,它的两个

参数分别为:const Coordinate &c1 和 const Coordinate &c2

在实现时:

Coordinate operator+(const Coordinate &c1,const Coordinate &c2)
{
    Coordinate temp;
    temp.m_iX=c1.m_iX+c2.m_iX;
    temp.m_iY=c1.m_iY+c2.m_iY;
    return temp;
}

在使用时:

 int main(void)
 {    
     Coordinate coor1(3,5);    
     Coordinate coor2(4,7);    
     Coordinate coor3(0,0);    
     coor3=coor1+coor2;//operator+(coor1,coor2)   
     return 0;
 }

使用时,其实和成员函数的加号 + 运算符重载是一样的,仍然要定义

3 个 Coordinate 的对象 coor1、coor2、coor3,将 coor1 与 coor2

相加的和赋值给 coor3,其实就相当于调用 operator+(coor1,coor2)。

(2)输出符号 « 的重载

class Coordinate
{
    friend ostream& operator<<(ostream &out,const Coordinate &coor);
    public:
      Coordinate(int x, int y);
    private:
      int m_iX;
      int m_iY;
}

将输出符号 « 的重载声明为友元函数 operator«(),它的返回值

必须是 ostream&,它的第一个参数也必须是一个 ostream 的引用,

第二个参数是要进行输出的对象 或引用(引用效率更高)

在实现时:

ostream& operator<<(ostream &out,const Coordinate &coor)
{
    out<<coor.m_iX<<","<<coor.m_iY;
    return out;
}

将 ostream 的对象引用 out 替代原来写成 cout 的位置,其他写法不变,

分别输出 m_iX 和 m_iY 的值,并一定要将 out 作为返回值返回出去

在使用时:

int main()
{
    Coordinate coor(3,5);
    cout<<coor;//operator<<(cout,coor);
    return 0;
}

定义一个 Coordinate 的对象 coor,通过 cout 就可以直接输出 coor 的

m_iX 和 m_iY,如果不进行运算符重载,这样写肯定是错误的,进行运算

符重载之后,这样写就相当于 operator«(cout,coor)

通过这个例子,从侧面也能看出: cout 其实就是一个对象,并且是一个

ostream 类型的对象

那么,输出运算符可以采用成员函数进行重载吗?

从成员函数重载的特点说起:

如果使用成员函数重载,如:上面的加号 + 运算符的重载,传入的

只有一个参数,这个参数其实是第二个加数,第一个加数默认就是

隐形的 this 指针,即 当前对象

可是,对于输出运算符来说,第一个参数必须是 ostream 的引用,

这就意味着第一个参数不能是隐形的 this 指针,二者是相冲突的

所以,当重载输出运算符 « 时,绝对不可以通过成员函数进行

重载,必须使用友元函数进行重载。