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

来源:https://www.cnblogs.com/xiaolincoding/archive/2019/12/01/11967836.html
-Advertisement-
Play Games

01 運算符重載的需求 C++ 預定義的運算符,只能用於基本數據類型的運算:整型、實型、字元型、邏輯型等等,且不能用於對象的運算。但是我們有時候又很需要在對象之間能用運算符,那麼這時我們就要 重載運算符 ,使得運算符能用於對象之間的運算。 比如,在數學上,兩個複數可以直接進行+、 等運算,但在C++ ...


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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近開始使用IDEA,突然發現的比較的實用的幾個快捷鍵 這些快捷鍵用的好的話真的可以提升很多效率 還有一些比較簡單的快捷鍵,相信大家都會 Ctrl+X:剪切 Ctrl+C:複製 Ctrl+V:粘貼 Ctrl+Shift+上下箭頭:註意它和圖片裡面移動代碼快捷鍵相識,自己體會 ...
  • 有興趣的可以看看註釋裡面的題目要求,自己寫寫或者看看下麵的用別的方式完成目標。 ...
  • 基礎入門知識(一) 一、java技術的分類 java按照技術標準和應用場景的不同分為三類,分別是JAVASE、JAVAEE、JAVAME JAVASE : 平臺標準版,用於開發部署桌面,伺服器以及嵌入式設備和實時環境中的java程式。 JAVAEE : 平臺企業版,開發便於組轉,可擴展,健壯,安全的 ...
  • 新聞 "擁抱可空引用類型" "介紹Orleans 3.0" 視頻及幻燈片 "組合的力量" "關於.NET:探索新的用於.NET的Azure .NET SDK" ".NET設計審查:GitHub快速審查" FableConf 2019 "OSS的樂趣" "走進編譯器與工具之旅" "使用響應式MVU釋放 ...
  • Spring Cloud Config為分散式系統提供了配置伺服器和配置客戶端,可以管理集群中的配置文件。 使用Git、SVN等版本管理系統存放配置文件,配置伺服器會到版本管理系統獲取配置,集群中的配置客戶端再到配置伺服器中獲取配置。 ...
  • [TOC] 1. 概述 本來是不想寫Paramiko的,因為我覺得之前的一篇關於Netmiko模塊更適合網工,後來發現paramiko有包含SFTP功能,所以還是有必要來講講,畢竟我們在設備上是要經常下載配置、上傳版本/升級版本用的,而且SFTP比FTP、TFTP更安全。 所以, 你也不用藉助其他工 ...
  • 01 實現自定義的可變長數組類型 假設我們要實現一個會自動擴展的數組,要實現什麼函數呢?先從下麵的main函數給出的實現,看看有什麼函數是需要我們實現的。 輸出結果: 要實現的方式,要做哪些事情呢?我先列一下: 要用動態分配的記憶體來存放數組元素,需要一個指針成員變數 重載賦值=運算符 重載[]運算符 ...
  • 01 賦值運算符重載的需求 有時候希望賦值運算符兩邊的類型可以不匹配,比如:把一個 int 類型變數賦值給一個Complex(複數)對象,或把一個 char 類型的字元串賦值給一個字元串對象,此時就需要重載賦值運算符‘=’。 需要註意的是:賦值運算符 只能重載為成員函數。 02 賦值運算符重載的例子 ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...