C++ 運算符重載的基本概念

01 運算符重載的需求

C++ 預約義的運算符,只能用於基本數據類型的運算:整型、實型、字符型、邏輯型等等,且不能用於對象的運算。可是咱們有時候又很須要在對象之間能用運算符,那麼這時咱們就要重載運算符,使得運算符能用於對象之間的運算。函數

好比,在數學上,兩個複數能夠直接進行+、-等運算,但在C++中,直接將+或-用於複數對象是不容許的。有時會但願,讓對象也能經過運算符進行運算。這樣代碼就更簡潔,也容易理解。code

例如:對象

complex_a 和 complex_b 是兩個複數對象,求兩個複數的和,但願的能直接寫成:complex_a + complex_b數學

這時咱們就須要對 + 號運算符進行重載。編譯


02 運算符重載的形式

運算符重載的實質就是函數重載,能夠重載爲普通函數,也能夠重載爲成員函數。運算符重載的基本形式以下: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


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對象,由於本次 - 號和 + 號運算符的函數執行以後,須要返回一個新的對象給到左值。

相關文章
相關標籤/搜索