运算符重载允许为类或结构体重新定义+、-、==等运算符行为,使对象能像基本类型一样进行操作,提升代码可读性与自然性。

在C++中,运算符重载是一种允许我们为自定义类型(如类或结构体)重新定义已有运算符行为的机制。通过它,我们可以让对象像基本数据类型一样使用+、-、==、
运算符重载的基本规则
要正确实现运算符重载,需遵循以下几点核心规则:
- 只能重载C++已有的运算符,不能创建新符号(例如无法定义**作为幂运算)
- 不能改变运算符的优先级和结合性
- 部分运算符必须作为类的成员函数重载(如=、[]、()、->、以及赋值复合运算符+=、-=等)
- 有些运算符建议以非成员函数形式实现(如>用于流输入输出)
- 重载函数至少有一个操作数是用户自定义类型
常见运算符重载示例
下面以一个简单的复数类Complex为例,展示几种典型运算符的重载方式。
1. 重载加法运算符 (+)
立即学习“C++免费学习笔记(深入)”;
可以作为成员函数或非成员函数实现。这里展示非成员版本:
class Complex {
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 提供访问接口
double getReal() const { return real; }
double getImag() const { return imag; }
// 声明友元以便访问私有成员
friend Complex operator+(const Complex& a, const Complex& b);};
// 非成员函数重载 +
Complex operator+(const Complex& a, const Complex& b) {
return Complex(a.real + b.real, a.imag + b.imag);
}
2. 重载赋值运算符 (=)
必须作为成员函数,并注意自我赋值和资源管理:
class String {
char* data;
public:
String(const char* str = nullptr);
~String();
// 赋值运算符重载
String& operator=(const String& other) {
if (this == &other) return *this; // 自我赋值检查
delete[] data; // 释放旧内存
if (other.data) {
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
} else {
data = nullptr;
}
return *this;
}};
3. 重载流插入运算符 (
通常用友元函数实现,便于访问私有成员并保持左操作数为ostream:
friend std::ostream& operator<<(std::ostream& os, const Complex& c) {
os << c.real;
if (c.imag >= 0) os << "+";
os << c.imag << "i";
return os;
}
4. 重载下标运算符 []
必须是成员函数,常用于模拟数组访问:
class MyArray {
int arr[10];
public:
int& operator[](int index) {
return arr[index]; // 返回引用,支持修改
}
const int& operator[](int index) const {
return arr[index]; // const版本,用于只读场景
}
};
注意事项与最佳实践
使用运算符重载时应注意语义一致性,避免滥用导致代码难以理解。
- 保持操作符原有直觉含义,比如+应表示“相加”,不应做减法
- 对于二元运算符,若不需要访问私有成员,优先考虑非成员函数以增强封装性
- 涉及动态资源时,务必同时实现析构函数、拷贝构造函数和赋值运算符(三大件)
- 复合赋值运算符(如+=)通常作为成员函数,而+可通过+=实现
例如,实现+的一种高效方式:
Complex& operator+=(const Complex& other) {
real += other.real;
imag += other.imag;
return *this;
}
// 利用 += 实现 +
Complex operator+(Complex a, const Complex& b) {
a += b;
return a;
}
基本上就这些。合理使用运算符重载能让类的行为更自然,但关键是要符合预期、逻辑清晰。











