C++中加號(hào)重載運(yùn)算符的具體使用
在 C++ 中,加號(hào)(+)運(yùn)算符重載 是最常用的運(yùn)算符重載場景之一,用于讓自定義類型(如類、結(jié)構(gòu)體)支持 + 操作(例如復(fù)數(shù)相加、自定義數(shù)值類型相加、字符串拼接等)。+ 是雙目運(yùn)算符(需要兩個(gè)操作數(shù)),重載方式分為「成員函數(shù)重載」和「全局函數(shù)(友元)重載」,兩種方式各有適用場景。
一、核心規(guī)則
- 運(yùn)算符重載后,優(yōu)先級(jí)、結(jié)合性、操作數(shù)個(gè)數(shù)與原生 + 完全一致;
重載的 + 應(yīng)遵循 “值語義”:通常返回新對(duì)象(而非修改原對(duì)象),符合用戶對(duì) + 的直覺(如 a + b 不改變 a 和 b,返回相加結(jié)果);
可重載為成員函數(shù)(左操作數(shù)是當(dāng)前類對(duì)象)或全局函數(shù) / 友元(支持左操作數(shù)為其他類型,如 int + 自定義類)。
二、兩種重載方式詳解
方式 1:成員函數(shù)重載 + 運(yùn)算符
語法:在類內(nèi)部聲明 / 定義成員函數(shù),格式為:
- 返回值類型 operator+(const 類名& 右操作數(shù)) const;
- onst 修飾成員函數(shù):保證不修改當(dāng)前對(duì)象(左操作數(shù)),符合 + 不改變原對(duì)象的語義;
- 右操作數(shù)用 const&:避免拷貝,且保證能接收常量對(duì)象;
返回值:返回新構(gòu)造的對(duì)象(相加結(jié)果)。
示例:復(fù)數(shù)類相加(成員函數(shù)重載)
#include <iostream>
using namespace std;
// 復(fù)數(shù)類:實(shí)部 + 虛部i
class Complex {
private:
double real; // 實(shí)部
double imag; // 虛部
public:
// 構(gòu)造函數(shù)
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// 成員函數(shù)重載 + 運(yùn)算符(左操作數(shù)是this,右操作數(shù)是c)
Complex operator+(const Complex& c) const {
// 不修改this和c,返回新的復(fù)數(shù)對(duì)象
return Complex(real + c.real, imag + c.imag);
}
// 打印函數(shù)
void print() const {
cout << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(1.5, 2.5), c2(3.5, 4.5);
Complex c3 = c1 + c2; // 等價(jià)于 c1.operator+(c2)
c1.print(); // 1.5 + 2.5i(原對(duì)象未修改)
c2.print(); // 3.5 + 4.5i(原對(duì)象未修改)
c3.print(); // 5 + 7i(相加結(jié)果)
return 0;
}
方式 2:全局函數(shù)(友元)重載 + 運(yùn)算符
當(dāng)需要支持「左操作數(shù)不是當(dāng)前類對(duì)象」的場景(如 int + Complex),成員函數(shù)重載無法實(shí)現(xiàn)(因?yàn)槌蓡T函數(shù)的左操作數(shù)必須是當(dāng)前類對(duì)象),此時(shí)需用全局函數(shù)重載,若需要訪問類的私有成員,可聲明為友元。
語法:
// 類內(nèi)聲明友元(如需訪問私有成員)
friend 返回值類型 operator+(const 類名& 左操作數(shù), const 類名& 右操作數(shù));
// 全局定義
返回值類型 operator+(const 類名& 左操作數(shù), const 類名& 右操作數(shù)) {
// 實(shí)現(xiàn)相加邏輯
}
示例 1:支持 Complex + Complex 和 int + Complex
#include <iostream>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// 聲明友元:支持 Complex + Complex
friend Complex operator+(const Complex& c1, const Complex& c2);
// 聲明友元:支持 int + Complex
friend Complex operator+(int num, const Complex& c);
// 聲明友元:支持 Complex + int(可選,對(duì)稱設(shè)計(jì))
friend Complex operator+(const Complex& c, int num);
void print() const {
cout << real << " + " << imag << "i" << endl;
}
};
// 全局定義:Complex + Complex
Complex operator+(const Complex& c1, const Complex& c2) {
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
// 全局定義:int + Complex
Complex operator+(int num, const Complex& c) {
return Complex(num + c.real, c.imag);
}
// 全局定義:Complex + int
Complex operator+(const Complex& c, int num) {
return Complex(c.real + num, c.imag);
}
int main() {
Complex c1(1.5, 2.5);
Complex c2 = 10 + c1; // int + Complex
Complex c3 = c1 + 20; // Complex + int
Complex c4 = c1 + c2; // Complex + Complex
c2.print(); // 11.5 + 2.5i
c3.print(); // 21.5 + 2.5i
c4.print(); // 13 + 5i
return 0;
}
三、特殊場景:重載 += 與 + 的配合
+= 是修改自身的運(yùn)算符(左操作數(shù)被修改),通常先重載 +=,再基于 += 重載 +,減少代碼冗余
#include <iostream>
using namespace std;
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 重載 +=(成員函數(shù),修改自身)
Complex& operator+=(const Complex& c) {
real += c.real;
imag += c.imag;
return *this; // 返回自身,支持鏈?zhǔn)讲僮鳎ㄈ?c1 += c2 += c3)
}
// 基于 += 重載 +(成員函數(shù))
Complex operator+(const Complex& c) const {
Complex temp = *this; // 拷貝當(dāng)前對(duì)象
temp += c; // 復(fù)用 += 邏輯
return temp;
}
void print() const {
cout << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(1, 2), c2(3, 4);
c1 += c2; // c1 被修改:4 + 6i
c1.print();
Complex c3 = c1 + c2; // c3:7 + 10i
c3.print();
return 0;
}
四、常見誤區(qū)與注意事項(xiàng)
1、返回值類型錯(cuò)誤:
+ 運(yùn)算符應(yīng)返回新對(duì)象(值返回),而非引用(引用會(huì)指向臨時(shí)對(duì)象,導(dǎo)致未定義行為);
+= 運(yùn)算符應(yīng)返回自身引用(Complex&),支持鏈?zhǔn)讲僮鳌?/p>
2、修改原對(duì)象:
重載 + 時(shí),切勿修改左 / 右操作數(shù)(違反用戶直覺),必須保證 a + b 不改變 a 和 b。
3、友元的濫用:
僅當(dāng)需要訪問私有成員時(shí)才將全局 + 聲明為友元,否則優(yōu)先用公共接口實(shí)現(xiàn)(如通過 getReal()/getImag() 獲取成員)。
4、不支持混合類型的對(duì)稱重載:
若需要 A + B 和 B + A 都生效,需分別重載兩個(gè)全局函數(shù)(如 operator+(A, B) 和 operator+(B, A))。
5、不能重載原生類型的 +:
C++ 不允許重載內(nèi)置類型(如 int + int)的運(yùn)算符,只能重載至少包含一個(gè)自定義類型的運(yùn)算符。
五、完整示例:字符串拼接(重載 +)
#include <iostream>
#include <cstring>
using namespace std;
class MyString {
private:
char* str;
int len;
public:
// 構(gòu)造函數(shù)
MyString(const char* s = "") {
len = strlen(s);
str = new char[len + 1];
strcpy(str, s);
}
// 析構(gòu)函數(shù)
~MyString() {
delete[] str;
}
// 拷貝構(gòu)造(避免淺拷貝)
MyString(const MyString& other) {
len = other.len;
str = new char[len + 1];
strcpy(str, other.str);
}
// 重載 +:字符串拼接
friend MyString operator+(const MyString& s1, const MyString& s2) {
MyString temp;
temp.len = s1.len + s2.len;
delete[] temp.str; // 釋放默認(rèn)構(gòu)造的空字符串
temp.str = new char[temp.len + 1];
strcpy(temp.str, s1.str);
strcat(temp.str, s2.str);
return temp;
}
// 打印字符串
void print() const {
cout << str << endl;
}
};
int main() {
MyString s1("Hello"), s2(" World!");
MyString s3 = s1 + s2;
s3.print(); // Hello World!
return 0;
}
總結(jié)
1、成員函數(shù)重載 +:適用于左操作數(shù)是當(dāng)前類對(duì)象的場景,語法簡潔,無需友元;
2、全局函數(shù)重載 +:適用于混合類型(如 int + 自定義類)或?qū)ΨQ重載的場景,需按需聲明友元;
3、遵循 “值語義”:+ 返回新對(duì)象,+= 返回自身引用,保證行為符合用戶直覺;
4、復(fù)用邏輯:優(yōu)先實(shí)現(xiàn) +=,再基于 += 實(shí)現(xiàn) +,減少代碼冗余
到此這篇關(guān)于C++中加號(hào)重載運(yùn)算符的具體使用的文章就介紹到這了,更多相關(guān)C++ 加號(hào)重載運(yùn)算符內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C生萬物C語言宏將整數(shù)二進(jìn)制位的奇偶數(shù)位交換
這篇文章主要為大家介紹了C生萬物C語言使用宏將整數(shù)二進(jìn)制位的奇偶數(shù)位交換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
C++ string和wstring相互轉(zhuǎn)換方式
這篇文章主要介紹了C++ string和wstring相互轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
vscode配置遠(yuǎn)程開發(fā)環(huán)境并遠(yuǎn)程調(diào)試運(yùn)行C++代碼的教程
這篇文章主要介紹了vscode配置遠(yuǎn)程開發(fā)環(huán)境并遠(yuǎn)程調(diào)試運(yùn)行C++代碼的教程,本文通過截圖實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
關(guān)于vector迭代器失效的幾種情況總結(jié)
下面小編就為大家?guī)硪黄P(guān)于vector迭代器失效的幾種情況總結(jié)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12
Linux網(wǎng)絡(luò)編程之基于UDP實(shí)現(xiàn)可靠的文件傳輸示例
這篇文章主要介紹了Linux網(wǎng)絡(luò)編程之基于UDP實(shí)現(xiàn)可靠的文件傳輸示例,是很實(shí)用的技巧,需要的朋友可以參考下2014-08-08
QT中QStringListModel類的應(yīng)用介紹
QStringListModel是最簡單的模型類,具備向視圖提供字符串?dāng)?shù)據(jù)的能力,本文主要介紹了QT中QStringListModel類的應(yīng)用介紹,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
OpenCV實(shí)現(xiàn)物體的凸包檢測的示例代碼
給定二維平面上的點(diǎn)集,凸包就是將最外層的點(diǎn)連接起來構(gòu)成的凸邊形,它是包含點(diǎn)集中所有的點(diǎn)。本文將利用OpenCV實(shí)現(xiàn)物體的凸包檢測,感興趣的可以了解一下2022-08-08

