發新話題

C++ Gossip - 物件基礎《封裝的進階議題》重載運算子

C++ Gossip - 物件基礎《封裝的進階議題》重載運算子

在C++中,預設除了基本資料型態可以使用運算子進行運算,例如int、double、char等,如果您要將兩個物件相加,預設上是不可行的。

然而很多情況下,您會想要將兩個物件的某些屬性值相加,並傳回運算後的結果,例如座標相加,如果您定義了Point2D類別,當中有x與y兩個屬性成員,您會想要透過+或-運算子的動作得到座標相加或相減的動作,或是透過++與--來達到遞增或遞減的運算,在C++中,這可以透過重載運算子來達到目的。

運算子的重載其實是函式重載的一個延伸應用,您指定要重載哪一個運算子,並在類別中定義運算子如何動作,運算子重載的語法宣告如下所示:
傳回值類別名稱:perator#(參數列) {
    // 實作重載內容
}


其中#中需指明您要重載哪一個運算子,例如重載一個+運算子,#處就替換為+運算子。

如果要重載++或--運算子,必須要注意到前置與後置的問題,例如一個變數x,您知道++前置時(++x)與++後置時(x++)實際上意義並不相同,在重載時為了要區別前置與後置,C++中使用一個int參數來作區別:
傳回型態 operator++();  // 前置,例如++x
傳回型態 operator++(int); // 後置,例如x++
傳回型態 operator--();  // 前置 ,例如 --x
傳回型態 operator--(int); // 後置,例如 x--


在後置中會傳入一個0,但實質上沒有作用,只是作為識別前置與後置之用,通常在重載++與--運算子時,前置與後置都要重載;下面這個範例告訴您如何重載 +與-運算子,以及++與--運算子,以完成上面所提及的座標相加、相減、遞增、遞減的運算:
  • Point2D.h
class Point2D {
public:
    Point2D();
    Point2D(int, int);
    int x() {return _x;}
    int y() {return _y;}
    Point2D operator+(const Point2D&);  // 重載+運算子
    Point2D operator-(const Point2D&);  // 重載-運算子
    Point2D& operator++();         // 重載++前置,例如 ++p
    Point2D operator++(int);      // 重載++後置,例如 p++
    Point2D& operator--();         // 重載--前置,例如 --p
    Point2D operator--(int);      // 重載--後置,例如 p--
   
private:
    int _x;
    int _y;        
};

  • Point2D.cpp
#include "oint2D.h"

Point2D:oint2D() {
    _x = 0;
    _y = 0;
}

Point2D:oint2D(int x, int y) {
    _x = x;
    _y = y;
}

Point2D Point2D:perator+(const Point2D &p) {
    Point2D tmp(_x + p._x, _y + p._y);
    return tmp;
}

Point2D Point2D:perator-(const Point2D &p) {
    Point2D tmp(_x - p._x, _y - p._y);
    return tmp;
}

Point2D& Point2D::operator++() {
    _x++;
    _y++;

    return *this;
}

Point2D Point2D::operator++(int) {
    Point2D tmp(_x, _y);
    _x++;
    _y++;

    return tmp;
}

Point2D& Point2D::operator--() {
    _x--;
    _y--;

    return *this;
}

Point2D Point2D::operator--(int) {
    Point2D tmp(_x, _y);
    _x--;
    _y--;

    return tmp;
}
  • main.cpp
#include <iostream>
#include "oint2D.h"
using namespace std;

int main() {
   Point2D p1(5, 5);
   Point2D p2(10, 10);
   Point2D p3;

    p3 = p1 + p2;
    cout << "p3(x, y) = ("
         << p3.x() << ", " << p3.y()
         << ")" << endl;

    p3 = p2 - p1;
    cout << "p3(x, y) = ("
         << p3.x() << ", " << p3.y()
         << ")" << endl;
         
    p3 = ++p1;
    cout << "p3(x, y) = ("
         << p3.x() << ", " << p3.y()
         << ")" << endl;   

    return 0;
}
執行結果:
p3(x, y) = (15, 15)
p3(x, y) = (5, 5)
p3(x, y) = (6, 6)

在重載+與-號運算子時,所接收的物件引數來自被重載的運算子右邊,例如在程式碼中加法運算時,+右邊是p2,所以傳入的物件引數就是p2物件,減法運算時-號右邊是p1,所以傳入的就是p1物件,在傳入引數時,您使用傳參考的方式進行,這可以省去物件複製的動作,您也可以不使用傳參考,這對這個程式並不造成結果的差異,但使用傳參考方式可以節省CPU在複製物件時的處理時間。

大部份的運算子都是可以被重載的,除了以下的運算子之外:
.   ::   .*   ?:

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。