C++入門《類和對象》之《運算符重載》詳解|成員函數重載/非成員函數重載

C++ 中,運算符重載是一種特殊的函數,它允許程序員為自定義的數據類型(如類和結構體)重新定義運算符的行為,使得這些運算符能夠像處理內置數據類型一樣處理自定義類型的數據。下面將從多個方面詳細講解 C++ 里的運算符重載。

基本語法?

運算符重載的本質是定義一個函數,其一般形式如下:

返回類型 operator運算符(參數列表) {// 函數體
}

其中,operator?是關鍵字,后面緊跟要重載的運算符,參數列表根據運算符的不同而有所變化。

運算符重載的類型

1. 成員函數重載

成員函數重載的運算符函數定義在類的內部,它隱含了一個?this?指針,指向調用該運算符的對象。

示例:

#include <iostream>class Complex {
private:double real;double imag;
public:Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}// 重載 + 運算符Complex operator+(const Complex& other) const {return Complex(real + other.real, imag + other.imag);}void display() const {std::cout << real << " + " << imag << "i" << std::endl;}
};int main() {Complex c1(1, 2);Complex c2(3, 4);Complex c3 = c1 + c2;c3.display();return 0;
}

在上述代碼中,operator+?是一個成員函數,它接受一個?const Complex&?類型的參數,返回一個新的?Complex?對象,表示兩個復數相加的結果。

2. 非成員函數重載

非成員函數重載的運算符函數定義在類的外部,通常用于需要訪問類的私有成員的情況,此時需要將該函數聲明為類的友元函數。

示例:

#include <iostream>class Complex {
private:double real;double imag;
public:Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}// 聲明友元函數friend Complex operator+(const Complex& c1, const Complex& c2);void display() const {std::cout << real << " + " << imag << "i" << std::endl;}
};// 非成員函數重載 + 運算符
Complex operator+(const Complex& c1, const Complex& c2) {return Complex(c1.real + c2.real, c1.imag + c2.imag);
}int main() {Complex c1(1, 2);Complex c2(3, 4);Complex c3 = c1 + c2;c3.display();return 0;
}

在這個例子中,operator+?是一個非成員函數,它接受兩個?const Complex&?類型的參數,返回一個新的?Complex?對象。通過將其聲明為?Complex?類的友元函數,它可以訪問?Complex?類的私有成員。

可重載和不可重載的運算符

  • 可重載的運算符:大多數運算符都可以重載,包括算術運算符(+-*/?等)、關系運算符(==!=<>?等)、邏輯運算符(&&||!)、位運算符(&|^?等)、賦值運算符(=+=-=?等)、自增自減運算符(++--)等。
  • 不可重載的運算符:一些運算符是不能重載的,如?.(成員訪問運算符)、.*(成員指針訪問運算符)、::(作用域解析運算符)、?:(條件運算符)和?sizeof?運算符。

注意事項

  • 不能改變運算符的優先級和結合性:運算符重載只是改變了運算符對自定義類型的操作行為,不能改變運算符原有的優先級和結合性。
  • 不能創建新的運算符:只能對已有的運算符進行重載,不能創造新的運算符。
  • 保持運算符的原有語義:在重載運算符時,應盡量保持運算符原有的語義,避免造成混淆。例如,重載?+?運算符應該實現加法的功能。

以下再舉幾個例子來解釋說明運算符重載相關注意事項

重載操作符至少有一個類類型參數,不能改變內置類型對象含義。

“不能寫?int operator+(int x, int y)?這種試圖改變內置?int?類型加法含義的重載函數”??

1. C++ 的設計原則

C++ 語言設計時,為了保證語言的穩定性和可預測性,規定內置數據類型的運算符行為是固定的,不能被修改。例如,對于兩個?int?類型的變量?a?和?ba + b?就是執行標準的整數加法運算,這是所有 C++ 程序員都默認和熟悉的行為。如果允許重載改變其含義,那么代碼的可讀性和一致性就會被破壞,可能會導致很多難以調試和理解的問題。

2. 示例說明

假設允許寫?int operator+(int x, int y)?這樣的函數來重載?int?類型的?+?運算符,比如:

int operator+(int x, int y) {return x * y;  // 這里試圖讓 + 運算符執行乘法的功能
}

然后在代碼中使用:

int main() {int num1 = 3;int num2 = 4;int result = num1 + num2;  // 按照正常理解應該是 3 + 4 = 7,但因為重載改變了行為,實際執行的是 3 * 4 = 12return 0;
}

這樣就會讓原本熟悉?int?類型加法的程序員產生困惑,并且可能在各種依賴于標準加法運算的代碼中引入錯誤,因為大家都默認?int?類型的?+?就是執行加法。

3. 正確的重載應用場景

運算符重載的正確使用場景是針對自定義類型。比如定義一個?Fraction?類表示分數:

class Fraction {
private:int numerator;  // 分子int denominator;  // 分母
public:Fraction(int num, int den) : numerator(num), denominator(den) {}// 重載 + 運算符,用于分數的加法Fraction operator+(const Fraction& other) {int newNumerator = numerator * other.denominator + other.numerator * denominator;int newDenominator = denominator * other.denominator;return Fraction(newNumerator, newDenominator);}
};

?在這個例子中,重載?+?運算符使得?Fraction?類型的對象可以像內置類型一樣進行加法操作,而不會影響?int?等內置類型的?+?運算符的正常行為。

重載函數參數個數

一元運算符有一個參數,二元運算符有兩個參數。成員函數形式的運算符重載,第一個運算對象由?this?指針隱式傳遞,參數比運算對象少

一個。

class Counter {
private:int count;
public:Counter(int c = 0) : count(c) {}// 成員函數形式重載 ++ 一元運算符Counter operator++() {count++;return *this;}
};

?上述代碼中,Counter?類以成員函數重載前置?++?運算符,它只有一個隱含的?this?指針,無需額外參數。

以重載前置自增運算符?++?為例,假設有一個?Counter?類表示計數器:

class Counter {
private:int value;
public:Counter(int v = 0) : value(v) {}// 重載前置自增運算符,一元運算符,有一個參數(隱含的this指針指向調用對象)Counter operator++() {value++;return *this;}void display() {std::cout << "Value: " << value << std::endl;}
};

在上述代碼中,operator++?是重載的前置自增運算符函數。當使用?++counter?(counter?是?Counter?類的對象)這樣的表達式時,operator++?函數被調用,this?指針指向?counter?對象,函數對?value?進行自增操作。從參數角度看,這個函數雖然沒有顯式的參數,但通過?this?指針隱式地接收了一個運算對象,也就是調用該運算符的對象本身。

二元運算符

二元運算符作用于兩個運算對象。在運算符重載函數中,就需要有兩個參數來分別接收這兩個運算對象。比如重載?+?運算符用于兩個自定義類對象相加。

假設有一個?Complex?類表示復數:

class Complex {
private:double real;double imag;
public:Complex(double r = 0, double i = 0) : real(r), imag(i) {}// 非成員函數重載 + 運算符,二元運算符,有兩個參數friend Complex operator+(const Complex& c1, const Complex& c2);
};Complex operator+(const Complex& c1, const Complex& c2) {return Complex(c1.real + c2.real, c1.imag + c2.imag);
}

這里的?operator+?函數是重載的?+?運算符函數,它有兩個參數?c1?和?c2?,分別代表?+?運算符左右兩邊的?Complex?類對象。當執行?Complex c3 = c1 + c2;?這樣的表達式時,c1?傳遞給第一個參數,c2?傳遞給第二個參數,函數執行復數相加的操作并返回結果。

成員函數形式的運算符重載

如果運算符重載函數是成員函數,那么第一個運算對象會默認通過?this?指針隱式傳遞,所以參數個數比運算對象的數量少一個。

還是以?Complex?類的?+?運算符重載為例,用成員函數形式來實現:

class Complex {
private:double real;double imag;
public:Complex(double r = 0, double i = 0) : real(r), imag(i) {}// 成員函數重載 + 運算符,二元運算符,但參數比運算對象少一個Complex operator+(const Complex& other) {return Complex(real + other.real, imag + other.imag);}
};

在這個成員函數形式的?operator+?中,只有一個參數?other?。當執行?Complex c3 = c1 + c2;?時,c1?是調用該成員函數的對象,通過?this?指針隱式傳遞,c2?傳遞給?other?參數。函數內部通過?this?指針訪問調用對象(c1?)的成員變量?real?和?imag?,并與?other?(c2?)的成員變量進行相加運算。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70271.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70271.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70271.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Salesforce 檢索Layout的設定

做了許多Object&#xff0c;卻想不起來怎么設置我的Listview的項目了。 問題&#xff1a; salesforce 最近參照したオブジェクト 表示項目を変更したいですが、「検索レイアウト」の選択メニューが該當オブジェクトのオブジェクトマネージャーから出てないです。 解決方法&am…

SECS/GEM300應用案例參考

GEM300 是一種用于半導體制造領域的通信協議標準&#xff0c;主要用于支持 300mm 晶圓制造的自動化生產。以下是 GEM300 的一些具體應用案例&#xff1a; 1. 半導體設備集成 設備制造商的應用&#xff1a;廣州金南瓜科技有限公司通過 GEM300 SDK&#xff0c;幫助國內多個半導體…

win10系統上的虛擬機安裝麒麟V10系統提示找不到操作系統

目錄預覽 一、問題描述二、原因分析三、解決方案四、參考鏈接 一、問題描述 win10系統上的虛擬機安裝麒麟V10系統提示找不到操作系統&#xff0c;報錯&#xff1a;Operating System not found 二、原因分析 國產系統&#xff0c;需要注意的點&#xff1a; 需要看你的系統類…

情書網源碼 情書大全帝國cms7.5模板

源碼介紹 帝國cms7.5仿《情書網》模板源碼&#xff0c;同步生成帶手機站帶采集。適合改改做文學類的網站。 效果預覽 源碼獲取 情書網源碼 情書大全帝國cms7.5模板

C語言題目:鏈表數據求和操作

題目描述 讀入10個復數&#xff0c;建立對應鏈表&#xff0c;然后求所有復數的和。 輸入格式 無 輸出格式 無 樣例輸入 1 2 1 3 4 5 2 3 3 1 2 1 4 2 2 2 3 3 1 1 樣例輸出 2323i 代碼功能概述 createNode 函數&#xff1a; 創建一個包含 10 個復數節點的鏈表。 每個…

STM32 ADC介紹(硬件原理篇)

目錄 背景 AD轉換器 采樣與保持 量化 編碼 AD轉換器轉換原理 DA轉換原理 AD轉換原理 1.逐次逼近型AD轉換器 2.并聯比較型AD轉換器 編碼器 同步D觸發器和邊沿D觸發器 基本RS觸發器 同步RS觸發器 同步D觸發器 邊沿型D觸發器&#xff08;維持-阻塞D觸發器&#xff…

公網遠程家里局域網電腦過程詳細記錄,包含設置路由器。

由于從校內遷居小區,校內需要遠程控制訪問小區內個人電腦,于是早些時間剛好自己是電信寬帶,可以申請公網ipv4不需要花錢,所以就打電話直接申請即可,申請成功后訪問光貓設備管理界面192.168.1.1,輸入用戶名密碼登錄超管(密碼是網上查下就有了)設置了光貓為橋接模式,然后…

流行編程語言全解析:優勢、應用與短板

Python&#xff1a; 優勢 Python 以其簡潔、易讀的語法聞名&#xff0c;新手能快速上手。豐富的庫和框架&#xff0c;能極大地提高開發效率。 適用領域 數據科學與分析&#xff1a;處理和分析大規模數據集&#xff0c;進行數據可視化。典型示例&#xff1a;Google 用 Pytho…

統信服務器操作系統V20 1070A 安裝docker新版本26.1.4

應用場景&#xff1a; 硬件/整機信息&#xff1a;x86平臺、深信服超融合平臺 OS版本信息&#xff1a;統信V20 1070a 1.獲取docker二進制包 鏈接: https://pan.baidu.com/s/1SukBlra0mQxvslTfFakzGw?pwd5s5y 提取碼: 5s5y tar xvf docker-26.1.4.tgz groupadd docker ch…

在 Vue 3 中使用 Lottie 動畫:實現一個加載動畫

在現代前端開發中&#xff0c;動畫是提升用戶體驗的重要元素之一。Lottie 是一個流行的動畫庫&#xff0c;它允許我們使用 JSON 文件來渲染高質量的動畫。本文將介紹如何在 Vue 3 項目中集成 Lottie 動畫&#xff0c;并實現一個加載動畫效果。 如果對你有幫助請幫忙點個&#x…

【Spring】Spring配置文件

目錄 ?什么是配置文件&#xff1f; 配置文件的作用 SpringBoot配置文件 配置文件格式 配置文件的優先級 properties配置文件說明 properties基本語法 讀取配置文件 properties缺點 yml配置文件說明 yml基本語法 使用yml連接數據庫 yml配置不同數據類型及null 注意…

藍橋杯篇---實時時鐘 DS1302

文章目錄 前言特點簡介1.低功耗2.時鐘/日歷功能3.32字節的額外RAM4.串行接口 DS1302 引腳說明1.VCC12.VCC23.GND4.CE5.I/O6.SCLK DS1302 寄存器1.秒寄存器2.分鐘寄存器3.小時寄存器4.日寄存器5.月寄存器6.星期寄存器7.年寄存器8.控制寄存器 DS1302 與 IAP25F2K61S2 的連接1.CE連…

Dubbo:高效的分布式服務框架

引言 在當今互聯網應用的快速發展中&#xff0c;微服務架構已經成為一種主流的設計模式&#xff0c;它將一個大型單體應用拆分成多個小型、松耦合的服務。Dubbo 作為一款由阿里巴巴開源的 RPC 服務框架&#xff0c;專門為解決分布式系統中服務通信和治理的問題而設計。本文將深…

Visual Studio Code使用ai大模型編成

1、在Visual Studio Code搜索安裝roo code 2、去https://openrouter.ai/settings/keys官網申請個免費的配置使用

【Javascript Day18】

目錄 標簽事件綁定的屬性參數 阻止默認行為 dialog的實現及組織冒泡&#xff08;捕獲&#xff09;傳遞 基于冒泡的事件委托 鍵盤事件的事件源對象信息 JS的自動觸發操作 標簽事件綁定的屬性參數 <!-- 標簽上的事件綁定&#xff0c;事件源對象通過 關鍵字event傳遞 --…

解鎖機器學習核心算法 | 支持向量機:機器學習中的分類利刃

一、引言 在機器學習的龐大算法體系中&#xff0c;有十種算法被廣泛認為是最具代表性和實用性的&#xff0c;它們猶如機器學習領域的 “十大神器”&#xff0c;各自發揮著獨特的作用。這十大算法包括線性回歸、邏輯回歸、決策樹、隨機森林、K - 近鄰算法、K - 平均算法、支持向…

玩客云 IP查找

1.玩客云使用靜態IP在不同網段路由器下不能使用&#xff0c;動態不好找IP地址 1.1使用python3 實現自動獲取發送 import requests import os import socket# 從環境變量獲取 PushPlus 的 token 和群組編碼 PUSH_PLUS_TOKEN os.getenv("PUSH_PLUS_TOKEN") PUSH_PLU…

Linux(Centos 7.6)命令詳解:cat

1.命令作用 將文件或標準輸入連接到標準輸出(Concatenate FILE(s), or standard input, to standard output)&#xff0c; 即將文件內容輸出到屏幕上&#xff0c;或者將多個文件合并成一個文件。 2.命令語法 Usage: cat [OPTION]... [FILE]... 3.參數詳解 OPTION: -A, -…

深入解析Qt事件循環

在Qt開發中&#xff0c;QApplication::exec()這行代碼是每個開發者都熟悉的“魔法咒語”。為什么GUI程序必須調用它才能響應操作&#xff1f;為何耗時操作會導致界面凍結&#xff1f;本文將以事件循環為核心&#xff0c;揭示Qt高效運轉的底層邏輯&#xff0c;探討其設計哲學與最…

Hive增量遷移方案與實操PB級

客戶一共1PB數據&#xff0c;每天新增10T&#xff0c;有些表只保留3天。 需要客戶提供&#xff1a; a.tbl_size(大小GB) a.last_mtime(最新更新時間) a.tbl_ttl(保留時間) b.last_part_dt(分區值) b.last_part_size(最新分區大小) t_day(表更新規律,t幾) 因為目前…