在C++中,运算符重载(Operator Overloading)允许我们为用户定义的类型(如类或结构体)赋予自定义的运算符行为。通过运算符重载,可以使代码更直观、更易读。
1. 运算符重载的基本语法
运算符重载是通过定义一个特殊的成员函数或全局函数来实现的。语法如下:
(1)成员函数形式
ReturnType operatorOp(ArgumentList);
-
operator
是关键字。 -
Op
是要重载的运算符(如+
、-
、*
等)。 -
ArgumentList
是运算符的参数列表。
(2)全局函数形式
ReturnType operatorOp(Argument1, Argument2);
-
全局函数形式通常用于需要对称性的运算符(如
+
、-
等)。
2. 可重载的运算符
C++中大部分运算符都可以重载,但以下运算符不能重载:
-
.
(成员访问运算符) -
.*
(成员指针访问运算符) -
::
(作用域解析运算符) -
?:
(三元条件运算符) -
sizeof
(大小运算符) -
typeid
(类型信息运算符)
3. 常见运算符重载示例
(1)重载 +
运算符
#include <iostream>
using namespace std;
class Point {
public:
int x, y;
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 成员函数形式重载 +
Point operator+(const Point& other) {
return Point(x + other.x, y + other.y);
}
};
int main() {
Point p1(1, 2);
Point p2(3, 4);
Point p3 = p1 + p2; // 调用重载的 + 运算符
cout << "p3: (" << p3.x << ", " << p3.y << ")" << endl;
return 0;
}
(2)重载 <<
运算符(输出流)
#include <iostream>
using namespace std;
class Point {
public:
int x, y;
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 全局函数形式重载 <<
friend ostream& operator<<(ostream& os, const Point& p);
};
ostream& operator<<(ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
int main() {
Point p(1, 2);
cout << "Point: " << p << endl; // 调用重载的 << 运算符
return 0;
}
(3)重载 ==
运算符
#include <iostream>
using namespace std;
class Point {
public:
int x, y;
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 成员函数形式重载 ==
bool operator==(const Point& other) {
return x == other.x && y == other.y;
}
};
int main() {
Point p1(1, 2);
Point p2(1, 2);
if (p1 == p2) { // 调用重载的 == 运算符
cout << "p1 and p2 are equal" << endl;
} else {
cout << "p1 and p2 are not equal" << endl;
}
return 0;
}
(4)重载 []
运算符
#include <iostream>
using namespace std;
class Array {
private:
int data[10];
public:
int& operator[](int index) {
if (index < 0 || index >= 10) {
throw out_of_range("Index out of range");
}
return data[index];
}
};
int main() {
Array arr;
arr[0] = 10; // 调用重载的 [] 运算符
cout << "arr[0]: " << arr[0] << endl;
return 0;
}
(5)重载 ()
运算符(函数调用运算符)
#include <iostream>
using namespace std;
class Adder {
public:
int operator()(int a, int b) {
return a + b;
}
};
int main() {
Adder add;
int result = add(1, 2); // 调用重载的 () 运算符
cout << "Result: " << result << endl;
return 0;
}
4. 运算符重载的限制
-
不能改变运算符的优先级和结合性。
-
不能创建新的运算符,只能重载已有的运算符。
-
不能改变运算符的操作数个数(如
+
是二元运算符,重载后也必须是二元运算符)。
5. 运算符重载的最佳实践
-
保持语义一致性:重载的运算符行为应与内置类型的行为一致。
-
避免过度使用:过度使用运算符重载可能导致代码难以理解。
-
优先使用成员函数形式:对于需要访问类私有成员的运算符,优先使用成员函数形式。
6. 总结
运算符重载是C++中强大的特性,可以为用户定义的类型赋予直观的操作行为。通过合理使用运算符重载,可以使代码更简洁、更易读。但需要注意保持语义一致性,避免滥用。