2014年7月18日 星期五

使用 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; 

沒有留言:

張貼留言