C++中加号重载运算符的具体使用
作者:挖矿大亨
在 C++ 中,加号(+)运算符重载 是最常用的运算符重载场景之一,用于让自定义类型(如类、结构体)支持 + 操作(例如复数相加、自定义数值类型相加、字符串拼接等)。+ 是双目运算符(需要两个操作数),重载方式分为「成员函数重载」和「全局函数(友元)重载」,两种方式各有适用场景。
一、核心规则
- 运算符重载后,优先级、结合性、操作数个数与原生 + 完全一致;
重载的 + 应遵循 “值语义”:通常返回新对象(而非修改原对象),符合用户对 + 的直觉(如 a + b 不改变 a 和 b,返回相加结果);
可重载为成员函数(左操作数是当前类对象)或全局函数 / 友元(支持左操作数为其他类型,如 int + 自定义类)。
二、两种重载方式详解
方式 1:成员函数重载 + 运算符
语法:在类内部声明 / 定义成员函数,格式为:
- 返回值类型 operator+(const 类名& 右操作数) const;
- onst 修饰成员函数:保证不修改当前对象(左操作数),符合 + 不改变原对象的语义;
- 右操作数用 const&:避免拷贝,且保证能接收常量对象;
返回值:返回新构造的对象(相加结果)。
示例:复数类相加(成员函数重载)
#include <iostream>
using namespace std;
// 复数类:实部 + 虚部i
class Complex {
private:
double real; // 实部
double imag; // 虚部
public:
// 构造函数
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// 成员函数重载 + 运算符(左操作数是this,右操作数是c)
Complex operator+(const Complex& c) const {
// 不修改this和c,返回新的复数对象
return Complex(real + c.real, imag + c.imag);
}
// 打印函数
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; // 等价于 c1.operator+(c2)
c1.print(); // 1.5 + 2.5i(原对象未修改)
c2.print(); // 3.5 + 4.5i(原对象未修改)
c3.print(); // 5 + 7i(相加结果)
return 0;
}
方式 2:全局函数(友元)重载 + 运算符
当需要支持「左操作数不是当前类对象」的场景(如 int + Complex),成员函数重载无法实现(因为成员函数的左操作数必须是当前类对象),此时需用全局函数重载,若需要访问类的私有成员,可声明为友元。
语法:
// 类内声明友元(如需访问私有成员)
friend 返回值类型 operator+(const 类名& 左操作数, const 类名& 右操作数);
// 全局定义
返回值类型 operator+(const 类名& 左操作数, const 类名& 右操作数) {
// 实现相加逻辑
}
示例 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(可选,对称设计)
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;
}
三、特殊场景:重载 += 与 + 的配合
+= 是修改自身的运算符(左操作数被修改),通常先重载 +=,再基于 += 重载 +,减少代码冗余
#include <iostream>
using namespace std;
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 重载 +=(成员函数,修改自身)
Complex& operator+=(const Complex& c) {
real += c.real;
imag += c.imag;
return *this; // 返回自身,支持链式操作(如 c1 += c2 += c3)
}
// 基于 += 重载 +(成员函数)
Complex operator+(const Complex& c) const {
Complex temp = *this; // 拷贝当前对象
temp += c; // 复用 += 逻辑
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;
}
四、常见误区与注意事项
1、返回值类型错误:
+ 运算符应返回新对象(值返回),而非引用(引用会指向临时对象,导致未定义行为);
+= 运算符应返回自身引用(Complex&),支持链式操作。
2、修改原对象:
重载 + 时,切勿修改左 / 右操作数(违反用户直觉),必须保证 a + b 不改变 a 和 b。
3、友元的滥用:
仅当需要访问私有成员时才将全局 + 声明为友元,否则优先用公共接口实现(如通过 getReal()/getImag() 获取成员)。
4、不支持混合类型的对称重载:
若需要 A + B 和 B + A 都生效,需分别重载两个全局函数(如 operator+(A, B) 和 operator+(B, A))。
5、不能重载原生类型的 +:
C++ 不允许重载内置类型(如 int + int)的运算符,只能重载至少包含一个自定义类型的运算符。
五、完整示例:字符串拼接(重载 +)
#include <iostream>
#include <cstring>
using namespace std;
class MyString {
private:
char* str;
int len;
public:
// 构造函数
MyString(const char* s = "") {
len = strlen(s);
str = new char[len + 1];
strcpy(str, s);
}
// 析构函数
~MyString() {
delete[] str;
}
// 拷贝构造(避免浅拷贝)
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; // 释放默认构造的空字符串
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;
}
总结
1、成员函数重载 +:适用于左操作数是当前类对象的场景,语法简洁,无需友元;
2、全局函数重载 +:适用于混合类型(如 int + 自定义类)或对称重载的场景,需按需声明友元;
3、遵循 “值语义”:+ 返回新对象,+= 返回自身引用,保证行为符合用户直觉;
4、复用逻辑:优先实现 +=,再基于 += 实现 +,减少代码冗余
到此这篇关于C++中加号重载运算符的具体使用的文章就介绍到这了,更多相关C++ 加号重载运算符内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
