前言
在 C++ 中最常用的運算子應該就是加 (+)、減 (-)、乘 (*) 、除 (/) 了。這些運算子都是二元的,意思是它們需要兩個運算元,一個在運算子的左側,一個在右側。
也因此,數一數二常見被多載的運算子就是加減乘除。當然還有其他常見的,但是在我們的例子中,我們會首先用加號 + 當作範例。
我們基本上有三種方式可以做到運算子多載:
- 友元函數 friend function
- 普通函數 normal function
- 成員函數 member function
在這篇文章中,我們將重點放在利用友函數 friend function 進行運算子多載,這對於大多數二元運算子來說比較常見。
接下來的幾篇,我們會再介紹其他兩種方法,並會在最後講到什麼時候該使用哪一種方法!
問題
前一章說到,有時候我們可能會想要使用一個沒有被定義的運算子使用方式,這樣程式碼就會出錯。
舉個例子大家會比較好懂:
class Money { private: int _dollars {}; public: Money(int dollars) : _dollars{ dollars } { } int getDollars() { return _dollars; } }; int main() { Money money1{ 1 }; Money money2{ 2 }; // 無法執行加法 std::cout << money1 + money2 << std::endl; return 0; }
在這個程式碼中,我們自己定義了一個類別 Money
,並在最後嘗試將兩個類別相加。
想當然,程式碼會報錯,因為我們沒有定義可以將 Money
相加的運算子使用方法。
這樣要如何解決呢?
解決方法
我們直接來看解決辦法:
class Money { private: int _dollars {}; public: Money(int dollars) : _dollars{ dollars } {} int getDollars() const { return _dollars; } friend Money operator+(const Money& m1, const Money& m2); }; Money operator+(const Money& m1, const Money& m2) { return m1._dollars + m2._dollars; } int main() { Money money1{ 1 }; Money money2{ 2 }; Money money3{ money1 + money2 }; std::cout << money3.getDollars() << std::endl; return 0; }
這樣的程式碼最後會輸出:
3
我們來看一下我們在這段程式碼中做了什麼事。
首先,我們知道如果要多載加號運算子,我們需要自己去多載 operator+
這個函數。
而這就是第 13 行所做的,將兩個 Money
物件中的成員 dollars
相加,最後返回型態 Money
。
另外,我們在第 10 行宣告函數 operator+
為類別 Money
的友函數,因此它才可以直接取得私有成員 dollars
。
同樣道理,你們可以自己去試著做做看其他運算子,比如說減法、乘法等等。
不同型態的運算元
好了,現在我們可以將兩個同樣是 Money
類別的物件相加了。但會不會有時我們想要做到類似這樣的事呢?
int dollar = 4; Money money{1}; // 想做以下這個 money + 4;
當然有可能!
想要做到這件事,我們就必續再多載一次運算子:
class Money { private: int _dollars {}; public: Money(int dollars) : _dollars{ dollars } {} int getDollars() const { return _dollars; } friend Money operator+(const Money& m1, const Money& m2); friend Money operator+(const Money& m1, const int dollar); }; Money operator+(const Money& m1, const Money& m2) { return m1._dollars + m2._dollars; } Money operator+(const Money& m1, const int dollar) { return m1._dollars + dollar; }
這樣我們就可以做到 money + 4
這件事啦!
但是有一件事非常重要!money + 4
和 4 + money
兩個用到的函數是不同的!這是因為加號左右兩邊的運算元型態並不相同。
因此如果想要做到 4 + money
,我們必須再多載一次:
Money operator+(const int dollar, const Money& m1) { return m1._dollars + dollar; }
總結
這篇我們終於學到可以如何多載一個運算子了!
多載運算子在進階的類別應用,或是在實際軟體世界中是非常常見的應用喔,因此這個概念非常重要!
那這篇就到這裡啦!有學到東西的話可以留五星評價喔!