C++ 預約義的運算符,只能用於基本數據類型的運算:整型、實型、字符型、邏輯型等等,且不能用於對象的運算。可是咱們有時候又很須要在對象之間能用運算符,那麼這時咱們就要重載運算符,使得運算符能用於對象之間的運算。函數
好比,在數學上,兩個複數能夠直接進行+、-等運算,但在C++中,直接將+或-用於複數對象是不容許的。有時會但願,讓對象也能經過運算符進行運算。這樣代碼就更簡潔,也容易理解。code
例如:對象
complex_a 和 complex_b 是兩個複數對象,求兩個複數的和,但願的能直接寫成:complex_a + complex_b數學
這時咱們就須要對 +
號運算符進行重載。編譯
運算符重載的實質就是函數重載,能夠重載爲普通函數,也能夠重載爲成員函數。運算符重載的基本形式以下:class
返回值類型 operator 運算符(形參表) { ... }
下面舉個例子,實現對複數對象的 +
和 -
運算符重載:構造函數
class Complex // 複數類 { public: // 構造函數,若是不傳參數,默認把實部和虛部初始化爲0 Complex(double r = 0.0, double i = 0.0):m_real(r),m_imag(i) { } // 重載-號運算符,屬於成員函數 Complex operator-(const Complex & c) { // 返回一個臨時對象 return Complex(m_real - c.m_real, m_imag - c.m_imag); } // 打印複數 void PrintComplex() { cout << m_real << "," << m_imag << endl; } // 將重載+號的普通函數,定義成友元函數 // 目的是爲了友元函數能訪問對象的私有成員 friend Complex operator+(const Complex &a, const Complex &b); private: double m_real; // 實部的值 double m_imag; // 虛部的值 }; // 重載+號運算符,屬於普通函數,不是對象的成員函數 Complex operator+(const Complex &a, const Complex &b) { // 返回一個臨時對象 return Complex(a.m_real + b.m_real, a.m_imag + b.m_imag); } int main() { Complex a(2,2); Complex b(1,1); Complex c; c = a + b; // 等價於c = operator+(a,b) c.PrintComplex(); c = a - b; // 等價於 c = a.operator-(b) c.PrintComplex(); return 0; }
輸出結果:數據類型
3,3 1,1
從上面的例子中,咱們能夠知道重載爲成員函數和普通函數的區別了:引用
c = a - b;
等價於 c = a.operator-(b)
c = a + b;
等價於c = operator+(a,b)
在上面的代碼中,我把重載 +
號運算符的普通函數,在Complex
複數類中定義成了友元函數,目的是爲了友元函數能訪問對象的私有成員,不然會編譯報錯。im
這裏還有個值得思考的問題:
Complex
對象而不是Complex &
呢?const Complex & c
常引用類型而不是Complex c
呢?// 重載-號運算符,屬於成員函數 Complex Complex::operator-(const Complex & c) { // 返回一個臨時對象 return Complex(m_real - c.m_real, m_imag - c.m_imag); }
首先先說一下參數表爲何是const Complex & c
常引用類型,首先若是參數表若是普通的對象形式Complex c
,那麼在入參的時候,就會調用默認的賦值(拷貝)構造函數,產生了一個臨時對象,這會增大開銷,因此就採用引用的方式,同時又爲了防止引用的對象被修改,因此就定義成了const Complex & c
常引用類型。
再來講一下返回值爲何是普通Complex
對象,由於本次 - 號和 + 號運算符的函數執行以後,須要返回一個新的對象給到左值。