01 運算子多載的需求
C++ 預定義的運算子,只能用于基本資料型別的運算:整型、實型、字符型、邏輯型等等,且不能用于物件的運算,但是我們有時候又很需要在物件之間能用運算子,那么這時我們就要多載運算子,使得運算子能用于物件之間的運算,
比如,在數學上,兩個復數可以直接進行+、-等運算,但在C++中,直接將+或-用于復數物件是不允許的,有時會希望,讓物件也能通過運算子進行運算,這樣代碼就更簡潔,也容易理解,
例如:
complex_a 和 complex_b 是兩個復數物件,求兩個復數的和,希望的能直接寫成:complex_a + complex_b
這時我們就需要對 + 號運算子進行多載,
02 運算子多載的形式
運算子多載的實質就是函式多載,可以多載為普通函式,也可以多載為成員函式,運算子多載的基本形式如下:
回傳值型別 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復數類中定義成了友元函式,目的是為了友元函式能訪問物件的私有成員,否則會編譯報錯,
03 +號和-號多載函式的回傳值和引數表
這里還有個值得思考的問題:
- 為什么多載-號和+號運算子函式的回傳型別是
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物件,因為本次 - 號和 + 號運算子的函式執行之后,需要回傳一個新的物件給到左值,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/83156.html
標籤:C++

