詳細介紹運算符重載函數,清晰明了

祝各位六一快樂~

前言

1.為什么要進行運算符重載?

C++中預定義的運算符的操作對象只能是基本數據類型。但實際上,對于許多用戶自定義類型(例如類),也需要類似的運算操作。這時就必須在C++中重新定義這些運算符賦予已有運算符新的功能,使它能夠用于特定類型執行特定的操作

C++為了增強代碼的可讀性引入了運算符重載,運算符重載是具有特殊函數名的函數,也具有其
返回值類型函數名字以及參數列表,其返回值類型與參數列表與普通的函數類似

2.什么是運算符重載 ?

運算符重載是通過創建運算符函數實現的,運算符函數定義了重載的運算符將要進行的操作。

1.基本知識

操作符重載,本質上就是函數重載(詳細了解可點擊閱讀函數重載),它大大豐富了已有操作符的含義,方便使用

運算符重載格式如下:

1.函數名:operator+需要重載的運算符符號

2.函數原型:返回值類型 operator+符號(形參參數列表)

3.必須有一個類類型的參數

4.? ? ?::? ? ?:? ? .? ? ? .*? ? ? ?sizeof? 這五個運算符不能重載

5.用于內置類型的運算符,其含義不能改變,例如:內置的整型+,不能改變其含義

6.作為類成員函數重載時,其形參看起來比操作數數目少1,因為成員函數的第一個參數為隱
藏的this

7.不能通過連接其他符號來創建新的操作符:比如operator@

8.運算符重載時必須遵循的原則

  • 重載運算符含義必須清楚;
  • 重載運算符不能有二義性。

9.算符函數重載的兩種形式

  • 重載為類的成員函數
  • 重載為類的非成員函數 (非成員函數通常是友元函數)。

注:可以把一個運算符作為一個非成員、非友元函數重載。但是,這樣的運算符函數訪問類的私有和保護成員時,必須使用類的公有接口中提供的設置數據和讀取數據的函數,調用這些函數時會降低性能。可以內聯這些函數以提高性能。

補充知識:友元函數

一、友元函數的作用

  • 提供數據共享接口:為不同類之間的成員函數,以及類的成員函數與一般函數之間提供了數據共享的接口。
  • 支持類間緊密協作:當兩個或多個類之間需要進行緊密的協作和交互時,友元函數允許直接訪問私有成員,減少系統開銷,提高效率。
  • 支持運算符重載:在某些情況下,可能需要重載運算符并操作兩個不同對象之間的私有數據。此時可以將相應操作符重載函數聲明為兩個類的友元。

二、友元函數的特點(重點)

  • 與類的成員函數具有一樣的權限:友元函數可以訪問類的所有成員,包括私有成員。
  • 不屬于任何類:友元函數是定義在類外的普通函數,不屬于任何類。
  • 沒有this指針:由于友元函數不是類的成員函數,因此它沒有this指針。

三、友元函數的用法

  • 聲明方式:友元函數需要在類中進行聲明,前面需要加上friend關鍵字,可以放在公有部分也可以放在私有部分。
  • 多類友元:一個函數可以是多個類的友元函數,只需要在個各類中分別進行聲明。
  • 調用方式:友元函數的調用與一般函數的調用方式和原理一致。

四、注意事項

  • 破壞封裝性:友元函數破壞了類的封裝性和類數據的隱藏性,因此在使用時需要謹慎考慮。
  • 避免過度使用:原則上應盡量少使用或不使用友元,除非確實能顯著提高開發效率。

    2.經典運算符重載的代碼示例(主要以日期類為例)

2.1operator+,operator-,operator+=,operator-=

以復數類為例

代碼

#include<iostream>
using namespace std;//負數類
class complex
{
public:complex(double r = 0, double i = 0) :_real(r), _imag(i) {}complex operator +(const complex& c); //+運算符complex operator -(const complex& c);//-運算符complex& operator +=(const complex& c); //+=運算符complex& operator -=(const complex& c);//-=運算符complex& operator - ();//求負運算符void Print()const{cout << "(" << _real << "," << _imag << ")" << endl;}
private:double _real;//實部double _imag;//虛部
};
complex complex::operator +(const complex& c) //+運算符
{complex tmp;tmp._real = _real + c._real;tmp._imag = _imag + c._imag;return tmp;
}
complex complex::operator -(const complex& c) //-運算符
{complex tmp;tmp._real = _real - c._real;tmp._imag = _imag - c._imag;return tmp;
}
complex& complex::operator +=(const complex& c) //+=運算符
{_real += c._real;_imag += c._imag;return *this;
}
complex& complex::operator -=(const complex& c) //-=運算符
{_real -= c._real;_imag -= c._imag;return *this;
}
complex& complex::operator - ()//求負運算符
{_real = -_real;_imag = -_imag;return *this;
}
int main()
{complex c1(3.5, 5), c2(6, 8), c3, c4, c5;c3 = c1 + c2;c3.Print();c4 = c2 - c1;c4.Print();c1 += c2;c1.Print();c2.Print();c2 -= c1;c1.Print();c2.Print();c5 = -c2;c5.Print();return 0;
}

2.2前置operator++(--),后置operator++(--)

前置++和后置++的函數名都是operator++(沒錯,又是函數重載),他們的區別在于前置++沒有形參,后置++有一個形參int,但是我們在實際上使用時并不需要給后置++的形參int傳實參,int只是為了區分前置++和后置++的標識。

前置--和后置--也是同樣用形參int來區分。

以日期類為例

#include<iostream>
using namespace std;
class Date
{
public:Date(int year = 0, int month = 0, int day = 0);// 拷貝構造函數// d2(d1)Date(const Date& d);// 獲取某年某月的天數int GetMonthDay(int year, int month);// 日期+=天數Date& operator+=(int day);// 日期+天數Date operator+(int day)const;// 日期-=天數Date& operator-=(int day);// 日期-天數Date operator-(int day)const;// 前置++Date& operator++();// 后置++Date operator++(int);// 后置--Date operator--(int);// 前置--Date& operator--();void print()const;// 析構函數(日期類無需清理資源,析構函數不必顯示寫)//void print();//~Date()//{//cout << "~Date()" << endl;//}
private:int _year, _month, _day;
};Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
Date::Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}
int Date::GetMonthDay(int year, int month)
{static int MonthDay[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)){return 29;}else{return MonthDay[month];}
}
void Date::print()const
{cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
Date& Date::operator+=(int day)
{if (day < 0){return *this -= -day;}_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_month = 1;_year++;}}return *this;
}
Date Date::operator+(int day)const
{Date tmp = *this;tmp += day;return tmp;
}
Date& Date::operator-=(int day)
{if (day < 0){return *this += -day;}_day -= day;while (_day <= 0){_month--;if (_month == 0){_year--;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}
Date Date::operator-(int day)const
{Date tmp = *this;tmp -= day;return tmp;
}
void Test1()
{Date d1(2024, 4, 30);Date d2 = d1 + 3;d2.print();Date d3(2024, 12, 31);Date d5 = d3;d3 += 1;d3.print();d5 = d5 - 1;d5.print();d1 -= 30;d1.print();Date d4 = d1 - 3;d4.print();
}
// 前置++
Date& Date::operator++()
{//這里直接用剛剛實現的Date& Date::operator+=(int day)//只是++相當于day=1而已//減少了代碼負擔*this += 1;return *this;
}
// 后置++
Date Date::operator++(int)
{//這里直接用剛剛實現的Date& Date::operator+(int day)Date tmp = *this;*this += 1;return tmp;
}
// 前置--
Date& Date::operator--()
{*this -= 1;return *this;
}
// 后置--
Date Date::operator--(int)
{Date tmp = *this;*this -= 1;return tmp;
}
void Test2()
{Date d1(2024, 6, 1);Date d2(2023, 12, 31);Date d3 = d1--;Date d4 = d2++;d3.print();d4.print();Date d5 = --d3;Date d6 = ++d4;d5.print();d6.print();
}
int main()
{//Test1();//可以自行測試Test2();
}

2.3operator<,operator<=,operator==,operator!=,operator>=,operator>

只需要實現operator<,operator==,其他的運算符重載就能輕松實現了,下面我們一起看一下吧

#include<iostream>
using namespace std;
class Date
{
public:Date(int year = 0, int month = 0, int day = 0);Date(const Date& d);// 獲取某年某月的天數int GetMonthDay(int year, int month);// >運算符重載bool operator>(const Date& d);// ==運算符重載bool operator==(const Date& d);// >=運算符重載bool operator >= (const Date& d);// <運算符重載bool operator < (const Date& d);// <=運算符重載bool operator <= (const Date& d);// !=運算符重載bool operator != (const Date& d);void print()const;private:int _year, _month, _day;
};Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
Date::Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}
int Date::GetMonthDay(int year, int month)
{static int MonthDay[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)){return 29;}else{return MonthDay[month];}
}
void Date::print()const
{cout << _year << "年" << _month << "月" << _day << "日" << endl;
}bool Date::operator < (const Date& d)
{if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if (_month == d._month){if (_day < d._day){return true;}}}return false;
}
bool Date::operator == (const Date& d)
{return _year == d._year&&_month == d._month&&_day == d._day;
}
bool Date::operator != (const Date& d)
{return !(*this == d);
}
bool Date::operator <= (const Date& d)
{return *this < d || *this == d;
}
bool Date::operator > (const Date& d)
{return !(*this <= d );
}
bool Date::operator >= (const Date& d)
{return !(*this < d);
}
int main()
{Date d1(2024, 3, 2), d2(2023, 5, 6);cout << (d1 == d2) << endl;cout << (d1 != d2) << endl;cout << (d1 <= d2) << endl;cout << (d1 >= d2) << endl;cout << (d1 < d2) << endl;cout << (d1 > d2) << endl;
}

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

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

相關文章

短信發送驗證碼及郵件發送驗證碼

發送短信驗證碼 阿里云發送驗證碼 public Integer sendTelCode(String tel) {String url "https://dfsns.market.alicloudapi.com/data/send_sms";String appcode "a3198282fbdf443d97aa9f3cfbe1232e";int code RandomUtil.randomInt(1000,10000);emai…

【DSP】xDAIS算法標準

1. 簡介 在安裝DSP開發支持包時&#xff0c;有名為 “xdais_7_21_01_07”文件夾。xDAIS全稱: TMS320 DSP Algorithm Standard(算法標準)。39條規則&#xff0c;15條指南。參考文檔。參考文章。 2. 三個層次 3.接口 XDAIS Digital Media。編解碼引擎。VISA&#xff08;Video&…

LeetCode前端刷題指南:探索四大領域,精通五大技能,掌握六大題型,運用七大策略

LeetCode前端刷題指南&#xff1a;探索四大領域&#xff0c;精通五大技能&#xff0c;掌握六大題型&#xff0c;運用七大策略 在前端開發的廣闊領域中&#xff0c;刷題是提高自身能力、深入理解算法和數據結構的重要途徑。LeetCode作為知名的在線刷題平臺&#xff0c;為前端開…

牛客小白月賽95VP

早上藍橋杯大寄&#xff0c;算是交了300元買了件T恤qaq 1.簽到&#xff1a;https://ac.nowcoder.com/acm/contest/83687/A 下面是AC代碼&#xff1a; #include<bits/stdc.h> using namespace std; int main() {int a,b;cin>>a>>b;if(ab) cout<<&quo…

簡述你對 SPA 單??的理解,它的優缺點分別是什么 ?

SPA&#xff08;Single-Page Application&#xff0c;單頁應用&#xff09;是一種在Web開發中廣泛使用的應用架構模式。它允許用戶通過交互操作來更新頁面的部分內容&#xff0c;而無需重新加載整個頁面。以下是關于SPA的理解、優點和缺點的簡要說明。 SPA的理解 SPA的核心思…

qi5uxeel算法分析流程記錄libmsec.so

動態注冊函數主要方法在so層。 libmsec.so 通過regsiterNative方法注冊62個函數 加殼混淆ollvm動態反調試等你還能再惡心點不 分析流程定位關鍵點 算法設計SM4以及各類自定義簽名算法 涉及到的知識包含Java C Android 完整混淆流程如下圖&#xff0c; 不得不說你開發的…

微信小程序canvas畫圖使用百分比適配不同機型屏幕達到任何屏幕比例皆可!完美適配任何機型!指定canvas尺寸適配亦可!保證全網唯一完美

錯誤代碼示例: // 在onLoad中調用 const that = this wx.getSystemInfo({success: function (res) {console.log(res)that.setData({model: res.model,screen_width: res.windowWidth/375,screen_height: res.windowHeight})} }) 我看到網上很多使用上面這種代碼去適配,其…

C語言 指針——函數指針

目錄 什么是函數指針&#xff1f; 函數指針的定義 定義函數指針時的常見錯誤 函數指針有什么用&#xff1f; 函數指針的主要應用 什么是函數指針&#xff1f; 函數指針 (Function Pointer) 就是指向函數的指針變量 數據類型 ( * 指針變量名 ) ( 形參列表 ); 例如&#x…

【回眸】牛客網刷刷刷(九) ——面試經驗篇(含參考回答)

前言 度過了忙碌的4個月&#xff0c;經歷了加班、籌備wedding、更新簡歷&#xff0c;終于有些許喘息時間。 下面的規劃比較簡單&#xff0c;一個是備考3個月后的雅思&#xff0c;一個是積累牛客網沖浪經驗&#xff0c;最后一個是記錄工作交接項。 牛客網刷刷刷這個系列也終于迎…

el-date-picker 選擇日期范圍只保存左側日期面板

需求 日期篩選&#xff0c;但限制只能選擇同一個月的數據&#xff0c;故此應該去掉右側月份面板。 實現 主要是通過 css 樣式實現&#xff1a; <style> /* 隱藏右邊日期面板 */ .el-picker-panel__content.el-date-range-picker__content.is-right .el-date-table, .…

拼多多商品信息一鍵抓取:深度解析商品詳情接口,Python實戰代碼來襲!

拼多多的商品詳情接口允許開發者通過指定的商品ID獲取商品的詳細信息&#xff0c;如商品標題、價格、描述、圖片等。接口采用HTTP請求方式&#xff0c;支持GET方法&#xff0c;返回格式為JSON。 三、接口調用 要調用拼多多的商品詳情接口&#xff0c;你需要遵循以下步驟&…

深度學習-01-作為“箱子“的變量

深度學習-01-作為"箱子"的變量 本文是《深度學習入門2-自製框架》 的學習筆記&#xff0c;記錄自己學習心得&#xff0c;以及對重點知識的理解。如果內容對你有幫助&#xff0c;請支持正版&#xff0c;去購買正版書籍&#xff0c;支持正版書籍不僅是尊重作者的辛勤勞…

6.12 Libbpf-bootstrap(三,APP)

一,APP 既然我們已經了解了最小應用以及Makefile中的編譯方式,接下來我們將通過bootstrap應用程序展示的一些額外的BPF特性。在現代BPF Linux環境中,bootstrap是我編寫可用于生產環境的BPF應用程序的方式。它依賴于BPF CO-RE(閱讀原因請點擊這里),并且需要Linux內核以CO…

Java基礎知識點(反射、注解、JDBC、TCP/UDP/URL)

文章目錄 反射反射的定義class對象反射的操作 注解注解的定義注解的應用注解的分類基準注解元注解 自定義注解自定義規則自定義demo JDBCTCP/UDP/URLTCPUDPURL 反射 反射的定義 Java Reflection是Java被視為動態語言的基礎啊&#xff0c; 反射機制允許程序在執行期間接入Refl…

[數據集][目標檢測]腦腫瘤檢測數據集VOC+YOLO格式9787張3類別

數據集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路徑的txt文件&#xff0c;僅僅包含jpg圖片以及對應的VOC格式xml文件和yolo格式txt文件) 圖片數量(jpg文件個數)&#xff1a;9787 標注數量(xml文件個數)&#xff1a;9787 標注數量(txt文件個數)&#xff1a;9787 標注…

【圖像增強處理工具】軟件使用說明書

軟件使用說明書 軟件名稱 圖像增強處理工具 軟件簡介 該軟件是一個基于 PySide6 和 OpenCV 的圖像處理工具,用戶可以通過 GUI 界面來執行圖像的旋轉、平移和鏡像操作,并將處理后的圖像保存到指定路徑。 運行軟件須知 確保 ui_form.py 文件在同一目錄下,該文件包含了通…

Bean-Searcher的使用提高查詢效率

Bean Searcher官網 添加pom.xml依賴 <dependency><groupId>cn.zhxu</groupId><artifactId>bean-searcher-boot-starter</artifactId><version>4.2.9</version> </dependency>在controller層注入 Autowiredprivate MapSearch…

淺談安科瑞ASJ10-LD1A智能漏電繼電器的設計與應用-安科瑞 蔣靜

一 產品簡介 功能 ASJ10-LD1A安科瑞智能電力繼電器 剩余電流保護可與低壓斷路器或低壓接觸器等組成組合式的剩余電流動作保護器&#xff0c;主要適用于交流50Hz&#xff0c;額定電壓為400V及以下的TT或TN系統配電線路&#xff0c;防止接地故障電流引起的設備和電氣火災事故&a…

AndroidStudio中debug.keystore的創建和配置使用

1.如果沒有debug.keystore,可以按照下面方法創建 首先在C:\Users\Admin\.android路徑下打開cmd窗口 之后輸入命令:keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -validity 10000 輸入兩次密碼(密碼不可見,打碼處隨便填寫沒關系) 2.在build…

詳解 JS 中的事件循環、宏/微任務、Primise對象、定時器函數,以及其在工作中的應用和注意事項

為什么會突然想到寫這么一個大雜燴的博文呢&#xff0c;必須要從筆者幾年前的一次面試說起 當時的我年輕氣盛&#xff0c;在簡歷上放了自己的博客地址&#xff0c;而面試官應該是翻了我的博客&#xff0c;好幾道面試題都是圍繞著我的博文來提問 其中一個問題&#xff0c;直接…