重载操作符

重载操作符

重载操作符Operator overloading是C++中一种特殊的语法,允许我们自定义一些运算符的行为,使它们能够用于自定义的数据类型。

例如,我们可以自定义一个加法运算符,使它能够直接对两个自定义类型的对象进行相加,而不需要额外的函数调用。这样可以使代码更加简洁、易读,并且提高了可重用性。

C++中可以重载的运算符包括算术运算符关系运算符逻辑运算符位运算符等等。需要注意的是,不能重载的运算符有:

作用域运算符 ::、成员访问运算符 .->、三目运算符 ?:、sizeof运算符和类型转换运算符 typeid

重载运算符的方法是在类中定义一个与运算符同名的函数,并在函数前加上关键字 operator,这样就可以对该运算符进行重载。


例如

重载加法运算符的示例代码:

  • 定义
1
2
3
4
5
6
7
8
9
10
class Complex {
public:
double real, imag;
Complex operator+ (const Complex& other) const {
Complex res;
res.real = real + other.real;
res.imag = imag + other.imag;
return res;
}
};
  • 主函数
1
2
3
4
5
6
7
8
int main() {
Complex c1 {1.0, 2.0};
Complex c2 {3.0, 4.0};
Complex c3 = c1 + c2;
cout << c3.real << " " << c3.imag << endl;

return 0;
}
  • 在这个示例中,我们定义了一个Complex类,其中包含两个成员变量realimag,表示实部虚部。然后我们通过重载加法运算符,使得Complex类型的对象可以直接相加,而不需要额外的函数调用。
  • 这里创建了两个复数对象c1c2,并将它们相加得到一个新的复数c3,然后输出c3的实部和虚部。

输出结果为:

1
4 6

再比如:

我们可以定义一个结构体类型表示这两个复数在复平面内的坐标,并重载加法运算符,使得我们可以直接对两个虚数进行相加。

示例代码:

  • 定义结构体
1
2
3
4
5
6
struct Complex {
double x, y;
Complex operator+ (const Complex& other) const {
return Complex {x + other.x, y + other.y};
}
};
  • 主函数
1
2
3
4
5
6
7
int main() {
Complex c1 {1.0, 2.0};
Complex c2 {3.0, 4.0};
Complex c3 = c1 + c2;
cout << c3.x << " " << c3.y << endl;
return 0;
}

在主函数中,我们定义了两个虚数v1v2,并将它们相加得到一个新的虚数v3。然后输出v3的分量xy

输出结果为:

1
4 6

当然

如果你是从这篇博客来的,那你应该希望了解这个:

  • 定义结构体
1
2
3
4
5
6
struct Edge{
int u, v, w;
bool operator<(const Edge &other) const{
return w < other.w;
}
}e[maxn];
  • 主函数
1
2
3
4
5
6
7
8
9
int main(){
int n, m;
cin >> n >> m;

for (int i = 1; i <= m; i++){
cin >> e[i].u >> e[i].v >> e[i].w;
}

sort(e + 1, e + m + 1);

很显然了, 在这里我们重载了小于号运算符,使得Edge类型的对象可以进行比较,并且满足严格弱序关系,所以可以使用sort函数Edge类型的对象进行排序,基本上与另外写一个cmp函数没有什么区别,但就是很有逼格所以,原代码改为这样,效果是一样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 5;
int fa[maxn];

struct Edge{
int u, v, w;
}e[maxn];

int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}

//-------------------------------------------------------
bool cmp(Edge x, Edge y){
return x.w < y.w;
}
//-------------------------------------------------------

int main(){
int n, m;
cin >> n >> m;

for (int i = 1; i <= m; i++){
cin >> e[i].u >> e[i].v >> e[i].w;
}

//-------------------------------------------------------
sort(e + 1, e + m + 1, cmp);
//-------------------------------------------------------

for (int i = 1; i <= n; i++){
fa[i] = i;
}

int ans = 0, cnt = 0;
for (int i = 1; i <= m; i++){
int fu = find(e[i].u), fv = find(e[i].v);
if (fu != fv){
fa[fu] = fv;
ans += e[i].w;
cnt++;
}
if (cnt == n - 1){
break;
}
}

cout << ans << endl;

return 0;
}

  • 需要注意的是,重载运算符时,必须保证操作数中至少有一个是用户自定义的类型,否则编译器无法识别。此外,重载的运算符必须具有合理的语义,不能与原有的语义相悖。