C++ 運(yùn)算符重載的使用
運(yùn)算符重載
(Operator Overloading)允許為自定義類型(如類、結(jié)構(gòu)體)賦予類似內(nèi)置類型的運(yùn)算符行為,使對(duì)象之間可以使用+、-、==、<<等運(yùn)算符進(jìn)行操作,提升代碼的可讀性和易用性。
1. 基本語法
- 通過
operator
關(guān)鍵字重載運(yùn)算符。 - 可以作為
成員函數(shù)
或全局函數(shù)
實(shí)現(xiàn)。
示例(成員函數(shù)):
class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} Point operator+(const Point& other) const { return Point(x + other.x, y + other.y); } };
2. 加號(hào)運(yùn)算符重載
成員函數(shù)方式:適用于a + b,其中a為當(dāng)前對(duì)象,b為參數(shù)
class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} // 加號(hào)運(yùn)算符重載 Point operator+(const Point& other) const { return Point(x + other.x, y + other.y); } }; int main() { Point p1(1, 2), p2(3, 4); Point p3 = p1 + p2; // 調(diào)用operator+ std::cout << p3.x << ", " << p3.y << std::endl; // 輸出4, 6 return 0; }
全局函數(shù)方式:適用于需要支持a + b和b + a等更靈活的場(chǎng)景(如左操作數(shù)不是類對(duì)象)。
class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} }; Point operator+(const Point& a, const Point& b) { return Point(a.x + b.x, a.y + b.y); }
注意事項(xiàng)
- 推薦參數(shù)為const引用,返回新對(duì)象。
- 不建議修改參與運(yùn)算的原對(duì)象(保持加法的“無副作用”)。
- 可重載為成員函數(shù)或全局函數(shù),具體選擇視需求而定。
總結(jié):
加號(hào)運(yùn)算符重載讓自定義類型支持直觀的“加法”操作,提升代碼可讀性和易用性。
3. 左移運(yùn)算符重載
左移運(yùn)算符重載(operator<<)常用于自定義類型的輸出,使對(duì)象可以直接用std::cout << obj的方式打印內(nèi)容。通常寫成全局函數(shù)
,并返回ostream&
以支持鏈?zhǔn)捷敵?/code>。
#include <iostream> class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} }; // 左移運(yùn)算符重載,必須為全局函數(shù)(或友元) std::ostream& operator<<(std::ostream& os, const Point& p) { os << "(" << p.x << ", " << p.y << ")"; return os; } int main() { Point p(3, 4); std::cout << p << std::endl; // 輸出:(3, 4) return 0; }
說明與注意事項(xiàng):
- 第一個(gè)參數(shù)為std::ostream&,第二個(gè)參數(shù)為自定義類型的const引用。
- 返回ostream&,支持鏈?zhǔn)捷敵觯ㄈ鐂td::cout << p1 << p2;)。
- 通常聲明為友元函數(shù)以訪問私有成員:
friend std::ostream& operator<<(std::ostream&, const Point&);
4. 遞增運(yùn)算符
遞增運(yùn)算符重載(operator++)允許自定義類型支持前置
和后置
自增(如++obj和obj++)。這兩種寫法的重載方式略有不同。
前置遞增運(yùn)算符重載:
- 語法:Type& operator++();
- 用于++obj,返回自增后的對(duì)象引用。
示例:
class Counter { int value; public: Counter(int v = 0) : value(v) {} // 前置++ Counter& operator++() { ++value; return *this; } int get() const { return value; } };
后置遞增運(yùn)算符重載:
- 語法:Type operator++(int);(int是占位參數(shù),用于區(qū)分前置和后置)
- 用于obj++,返回自增前的對(duì)象副本。
示例:
class Counter { int value; public: Counter(int v = 0) : value(v) {} // 后置++ Counter operator++(int) { Counter temp = *this; ++value; return temp; } int get() const { return value; } };
調(diào)用:
int main() { Counter c(5); ++c; // 前置,c變?yōu)? c++; // 后置,c變?yōu)? std::cout << c.get() << std::endl; // 輸出7 return 0; }
注意事項(xiàng)
- 前置返回引用,后置返回副本。
- 推薦前置效率更高,后置因需保存臨時(shí)副本略慢。
- 可根據(jù)需要只重載一種或兩種。
5. 賦值運(yùn)算符
賦值運(yùn)算符重載(operator=)允許自定義類型支持對(duì)象間的賦值操作(如a = b;)。正確實(shí)現(xiàn)賦值運(yùn)算符對(duì)于資源管理(如動(dòng)態(tài)內(nèi)存)尤為重要。
基本語法:
class Demo { public: Demo& operator=(const Demo& other) { if (this != &other) { // 防止自賦值 // 釋放舊資源(如有) // 復(fù)制other的數(shù)據(jù)到當(dāng)前對(duì)象 } return *this; // 支持鏈?zhǔn)劫x值 } };
典型實(shí)現(xiàn):
class MyString { char* data; public: MyString(const char* str = "") { data = new char[strlen(str) + 1]; strcpy(data, str); } ~MyString() { delete[] data; } MyString& operator=(const MyString& other) { if (this != &other) { delete[] data; // 釋放舊內(nèi)存 data = new char[strlen(other.data) + 1]; strcpy(data, other.data); } return *this; } };
注意事項(xiàng):
- 防止自賦值:if (this != &other),避免自我釋放導(dǎo)致數(shù)據(jù)丟失。
- 釋放舊資源:先釋放當(dāng)前對(duì)象持有的資源,防止內(nèi)存泄漏。
- 深拷貝:如有指針成員,需分配新內(nèi)存并復(fù)制內(nèi)容。
- 返回自身引用:return *this;,支持鏈?zhǔn)劫x值(如a = b = c;)。
6. 關(guān)系運(yùn)算符重載
關(guān)系運(yùn)算符重載允許自定義類型支持比較操作(如==、!=、<、>、<=、>=),使對(duì)象之間可以像內(nèi)置類型一樣進(jìn)行比較。
常見關(guān)系運(yùn)算符重載:
- operator==:等于
- operator!=:不等于
- operator< :小于
- operator> :大于
- operator<=:小于等于
- operator>=:大于等于
示例
class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} // 等于運(yùn)算符重載 bool operator==(const Point& other) const { return x == other.x && y == other.y; } // 小于運(yùn)算符重載(按字典序) bool operator<(const Point& other) const { return (x < other.x) || (x == other.x && y < other.y); } }; int main() { Point p1(1, 2), p2(1, 2), p3(2, 3); std::cout << std::boolalpha; std::cout << (p1 == p2) << std::endl; // true std::cout << (p1 < p3) << std::endl; // true return 0; }
注意事項(xiàng):
- 推薦參數(shù)為const引用,成員函數(shù)加const保證不修改對(duì)象。
- 只需重載==和<,其余可用標(biāo)準(zhǔn)庫std::rel_ops自動(dòng)推導(dǎo)(或手動(dòng)實(shí)現(xiàn))。
- 關(guān)系運(yùn)算符重載應(yīng)符合直觀語義,避免誤用。
7. 函數(shù)調(diào)用運(yùn)算符重載
函數(shù)調(diào)用運(yùn)算符重載(operator())允許對(duì)象像函數(shù)一樣被調(diào)用
,這種對(duì)象稱為“仿函數(shù)
”或“函數(shù)對(duì)象
”。
函數(shù)調(diào)用運(yùn)算符重載(operator())
- 通過重載operator(),可以讓對(duì)象像函數(shù)一樣使用,常用于
自定義算法、回調(diào)、STL
等場(chǎng)景。
示例:
class Adder { int base; public: Adder(int b) : base(b) {} int operator()(int x) const { return base + x; } }; int main() { Adder add5(5); std::cout << add5(10) << std::endl; // 輸出15 return 0; }
- 可以有多個(gè)參數(shù),也可以重載多次實(shí)現(xiàn)不同參數(shù)列表。
- 支持捕獲狀態(tài)(如成員變量),比普通函數(shù)更靈活。
8. 其他運(yùn)算符重載
下標(biāo)運(yùn)算符重載(operator[]):使對(duì)象支持?jǐn)?shù)組下標(biāo)訪問
示例:
class Array { int data[10]; public: int& operator[](int idx) { return data[idx]; } };
箭頭運(yùn)算符重載(operator->):使對(duì)象像指針一樣訪問成員。
class Ptr { Demo* p; public: Demo* operator->() { return p; } };
類型轉(zhuǎn)換運(yùn)算符重載(operator 類型):實(shí)現(xiàn)對(duì)象到其他類型的隱式或顯式轉(zhuǎn)換。
class Demo { int value; public: operator int() const { return value; } };
9. 注意事項(xiàng)
- 運(yùn)算符重載應(yīng)符合直觀語義,避免濫用。
- 某些運(yùn)算符(如[]、()、->、=)必須為成員函數(shù)。
- 運(yùn)算符重載不能改變運(yùn)算符的優(yōu)先級(jí)和結(jié)合性。
到此這篇關(guān)于C++ 運(yùn)算符重載的使用的文章就介紹到這了,更多相關(guān)C++ 運(yùn)算符重載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++ signal實(shí)現(xiàn)發(fā)送信號(hào)
這篇文章主要為大家詳細(xì)介紹了c++ signal實(shí)現(xiàn)發(fā)送信號(hào)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01C++編程之CString、string與、char數(shù)組的轉(zhuǎn)換
這篇文章主要介紹了C++編程之CString、string與、char數(shù)組的轉(zhuǎn)換的相關(guān)資料,希望通過本文能幫助到大家,讓大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下2017-10-10C語言實(shí)現(xiàn)經(jīng)典小游戲井字棋的示例代碼
這個(gè)三子棋游戲是在學(xué)習(xí)C語言的過程中自己編寫的一個(gè)小游戲,現(xiàn)在將自己的思路(主要以流程圖形式和代碼中的注釋表達(dá))和具體代碼以及運(yùn)行結(jié)果分享出來以供大家學(xué)習(xí)參考,希望對(duì)大家有所幫助2022-11-11C++使用鏈表存儲(chǔ)實(shí)現(xiàn)通訊錄功能管理
這篇文章主要為大家詳細(xì)介紹了C++使用鏈表存儲(chǔ)實(shí)現(xiàn)通訊錄功能管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06