C++類和對象之運算符重載解讀
C++ 運算符重載
一、什么是運算符重載?
運算符重載是 C++ 的一種特性,它允許程序員為自定義類型(如類和結構體)重新定義運算符的行為。通過運算符重載,我們可以使用熟悉的運算符語法來操作自定義類型的對象,從而使代碼更加簡潔、直觀。
當運算符被?于類類型的對象時,C++語?允許我們通過運算符重載的形式指定新的含義。C++規(guī)定類類型對象使?運算符時,必須轉換成調?對應運算符重載,若沒有對應的運算符重載,則會編譯報錯。
例如,我們可以為自定義的復數類重載 + 運算符,使得兩個復數對象可以直接使用 + 進行相加:
Complex a(1, 2); Complex b(3, 4); Complex c = a + b; // 使用重載的 + 運算符
二、運算符重載的語法規(guī)則
在 C++ 中,運算符重載通過定義特殊的成員函數或非成員函數來實現(xiàn)。
其基本語法如下:
返回類型 operator運算符(參數列表) {
// 函數體
}其中:
operator是 C++ 的關鍵字,用于聲明一個運算符重載函數。- 運算符 是要重載的運算符,如
+,-,*,/等。 - 返回類型 是運算符重載函數的返回值類型,通常與操作數的類型相關。
- 參數列表 是運算符重載函數的參數,參數的個數和類型取決于運算符的種類和重載方式。
注意:
- ?個類需要重載哪些運算符,是看哪些運算符重載后有意義
- 重載++運算符時,有前置++和后置++,運算符重載函數名都是operator++,?法很好的區(qū)分。C++規(guī)定,后置++重載時,增加?個int形參,跟前置++構成函數重載,?便區(qū)分。
- 當運算符被?于類類型的對象時,C++語?允許我們通過運算符重載的形式指定新的含義。C++規(guī)定類類型對象使?運算符時,必須轉換成調?對應運算符重載,若沒有對應的運算符重載,則會編譯報錯。
- 運算符重載是具有特殊名字的函數,他的名字是由operator和后?要定義的運算符共同構成。和其他函數?樣,它也具有其返回類型和參數列表以及函數體。
- 重載運算符函數的參數個數和該運算符作?的運算對象數量?樣多。?元運算符有?個參數,?元運算符有兩個參數,?元運算符的左側運算對象傳給第?個參數,右側運算對象傳給第?個參數。
- 如果?個重載運算符函數是成員函數,則它的第?個運算對象默認傳給隱式的this指針,因此運算符重載作為成員函數時,參數?運算對象少?個。
- 運算符重載以后,其優(yōu)先級和結合性與對應的內置類型運算符保持?致。
- 不能通過連接語法中沒有的符號來創(chuàng)建新的操作符:?如operator@。
重載<<和>>時,需要重載為全局函數,因為重載為成員函數,this指針默認搶占了第?個形參位置,第?個形參位置是左側運算對象,調?時就變成了 對象<<cout,不符合使?習慣和可讀性。
重載為全局函數把ostream/istream放到第?個形參位置就可以了,第?個形參位置當類類型對象。
成員函數重載
運算符重載函數可以作為類的成員函數來定義。在這種情況下,函數的參數個數比運算符的操作數少一個,因為第一個操作數是通過 this 指針隱式傳遞的。
非成員函數重載
運算符重載函數也可以作為非成員函數(全局函數或友元函數)來定義。
在這種情況下,函數的參數個數與運算符的操作數相同。
賦值運算符重載
賦值運算符重載是?個默認成員函數,?于完成兩個已經存在的對象直接的拷?賦值,這?要注意跟拷?構造區(qū)分,拷?構造?于?個對象拷?初始化給另?個要創(chuàng)建的對象。
賦值運算符重載的特點:
- 賦值運算符重載是?個運算符重載,規(guī)定必須重載為成員函數。賦值運算重載的參數建議寫成const當前類類型引?,否則會傳值傳參會有拷?
- 有返回值,且建議寫成當前類類型引?,引?返回可以提?效率,有返回值?的是為了?持連續(xù)賦值場景。
- 沒有顯式實現(xiàn)時,編譯器會?動?成?個默認賦值運算符重載,默認賦值運算符重載?為跟默認拷?構造函數類似,對內置類型成員變量會完成值拷?/淺拷?(?個字節(jié)?個字節(jié)的拷?),對?定義類型成員變量會調?他的賦值重載函數。
拷貝構造:一個存在的對象去初始化另一個要實例化的對象; 賦值重載:已存在的兩個對象之間的拷貝,注意返回值為類類型,處理連續(xù)賦值的情況
取地址運算符重載
const成員函數
- 將const修飾的成員函數稱之為const成員函數,const修飾成員函數放到成員函數參數列表的后?。
- const實際修飾該成員函數隱含的this指針,表明在該成員函數中不能對類的任何成員進?修改。Date* const this 變?yōu)?const Date* const this
取地址運算符重載
- 取地址運算符重載分為普通取地址運算符重載和const取地址運算符重載,?般這兩個函數編譯器?動?成的就可以夠我們?了,不需要去顯?實現(xiàn)。
- 除??些很特殊的場景,?如我們不想讓別?取到當前類對象的地址,就可以??實現(xiàn)?份,胡亂返回?個地址。
三、可重載的運算符和不可重載的運算符
可重載的運算符
C++ 中大部分運算符都可以被重載,包括:
- 算術運算符:
+,-,*,/,%,++,-- - 比較運算符:
==,!=,<,>,<=,>= - 邏輯運算符:
&&,||,! - 位運算符:
&,|,^,~,<<,>> - 賦值運算符:
=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>= - 其他運算符:
[],(),->,,,*(解引用),&(取地址)
不可重載的運算符
C++ 中少數運算符不能被重載,包括:
- 作用域解析運算符:
:: - 成員訪問運算符:
.和.* - 條件運算符:
?: - 類型轉換運算符:
typeid和dynamic_cast等 - 編譯時運算符:
sizeof
五、運算符重載的注意事項
在使用運算符重載時,需要注意以下幾點:
- 遵循運算符的原有語義:運算符重載應該保持運算符原有的語義,避免造成混淆。例如,重載
+運算符應該實現(xiàn)加法的語義,而不是減法。 - 不要濫用運算符重載:雖然運算符重載可以使代碼更加簡潔,但過度使用或濫用會使代碼變得難以理解和維護。
- 保持運算符的優(yōu)先級和結合性:運算符重載不能改變運算符的優(yōu)先級和結合性,這是由語言規(guī)定的。
- 正確處理 const 對象:如果運算符重載函數不修改對象的狀態(tài),應該將其聲明為
const成員函數。 - 注意內存管理:在重載賦值運算符和拷貝構造函數時,需要特別注意深拷貝和淺拷貝的問題,避免內存泄漏。
- 避免創(chuàng)建新的運算符:C++ 不允許創(chuàng)建新的運算符,只能重載已有的運算符。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
C/C++計算程序執(zhí)行時間的幾種方法實現(xiàn)
本文主要介紹了C/C++計算程序執(zhí)行時間的幾種方法實現(xiàn),包括使用clock()函數、使用庫和使用time.h頭文件中的time()函數,具有一定的參考價值,感興趣的可以了解一下2025-02-02

