使用 friend 函式重載運算子


使用類別成員來超載二元運算子時,會有一個限制,就是運算子的左邊一定要是原物件,您可以使用類別成員重載運算子具有以下的功能:
Point2D p1(10, 10);
Point2D p2;
p2 = p1 + 10;

但是使用類別成員重載,您就無法使用這個方法讓運算子重載有以下的功能:
Point2D p1(10, 10);
Point2D p2;
p2 = 1 + p1;

您可以規避這個問題,但每次都要讓其它型態的運算元置於運算子右邊也是蠻麻煩的,而且有時會容易出錯,這時您可以使用friend函式來重載運算子,使用 friend函式重載二元運算子時,您要指定兩個參數型態,分別表式運算子左右邊的運算元型態,您可以藉由安排這兩個參數來解決以上的問題,例如先如下定 義Point2D.h:
class Point2D {
public:
    ....
    friend Point2D operator+(const Point2D&, int); // 例如p+10
    friend Point2D operator+(int, const Point2D&); // 例如10+p
   
private:
    int _x;
    int _y;       
};

再實作Ball.cpp:
#include "Point2D.h"
....
Point2D operator+(const Point2D &p, int i) {
    Point2D tmp(p._x + i, p._y + i);

    return tmp;
}

Point2D operator+(int i, const Point2D &p) {
    Point2D tmp(i + p._x, i + p._y);

    return tmp;
}

接著您就可以直接如下進行運算:
Point2D p1(5, 5);
Point2D p2;
p2 = 10 + p1;

您也可以使用friend函式來重載++或--這類的一元運算子,但要注意的是,friend不會有this指標,所以為了讓它具有++或--的遞增遞減 原意,您要使用傳參考的方式,將物件的位址告訴函式,例如:
class Point2D {
public:
    ....
    friend Point2D operator++(Point2D&);  // 前置
    friend Point2D operator++(Point2D&, int); // 後置
   
private:
    int _x;
    int _y;       
};

實作時如下:
#include "Point2D.h"
....
Point2D operator++(Point2D &p) {
    p._x++;
    p._y++;
 
    return p;
}

Point2D operator++(Point2D &p, int) {
    Point2D tmp(p._x, p._y);

    p._x++;
    p._y++;

    return tmp;
}