运算符重载函数operator的简单用法与常用案例

运算符重载函数operator的简单用法与常用案例_重载符排序-CSDN博客

目录

一、operator重载运算符的介绍

二、案例

1、重载+号,返回值类型的使用

[2、重载<(小于号),定义结构体排序规则](#3. sort排序结构体,运算符重载实现)

3、重载<(小于号)map,set等容器自带排序规则


一、operator重载运算符的介绍

<返回类型说明符> operator <运算符符号>(<参数表>) { <函数体> }

示例: 给node结构体重载小于号(首先比较x,如果x相同比较y)

1
2
3
4
5
6
7
struct node{
int x, y;
bool operator <(const node &a) const {
if (x != a.x) return x < a.x;
return y < a.y;
}
};

点击并拖拽以移动

  • *bool*: 这是函数的返回类型。*operator<* 是一个比较运算符,通常用于比较两个对象并返回一个布尔值(truefalse)来表示第一个对象是否小于第二个对象。
  • *operator<*: 这是重载的比较运算符。在C++中,你可以为自定义类型重载运算符,以便它们可以像内置类型一样使用。在这个例子中,我们重载了 < 运算符,以便可以比较两个 node 对象。
  • const node &a
  1. const:表示这个引用指向的对象在函数内部不会被修改。
  2. node:这是参数的类型,即我们正在比较的另一个 node 对象。
  3. &:表示这是一个引用,而不是一个值拷贝,可以避免不必要的对象拷贝,提高性能。
  4. a:这是参数的名称,在函数体内部,可以通过 a 来访问传入的 node 对象。
  • 第二个 *const*: 它表明这个函数是一个常量成员函数。这意味着它可以在常量对象上调用,因为调用这个函数不会改变对象的状态。如果没有这个尾随的 const,那么以下代码将会导致编译错误:

  • const node n1{1, 2};  
    const node n2{2, 3};  
      if (n1 < n2) { // Error if operator< is not const  
        // ...  
    }
    // 因为 n1 是一个常量对象,所以你不能调用一个非 const 成员函数
    
    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

    ![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)

    ## 二、案例

    ### 1、重载+号,返回值类型的使用

    \1. 结构体间相加得到结构体

    ```cpp
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1000010;
    struct node{
    int x, y;
    //返回值int
    int operator +(const node &e)const {
    // 返回结果, 这里的+号为int间的+号,也就是普通的+号
    return e.x + x + e.y + y;
    }
    }f[N];
    int main()
    {
    f[1].x = 2, f[1].y = 10;
    f[2].x = 3, f[2].y = 11;
    // node之间的+以重载,返回值int
    int res = f[1] + f[2];
    cout << res <<endl;
    return 0;
    }

点击并拖拽以移动

输出结果: 26

解释: 相加的结果类型为填写+返回值的类型也就是int,相加规则:2+3+10+11

\2. 结构体间相加得到整型(int)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<bits/stdc++.h>
using namespace std;
const int N = 1000010;
struct node{
int x, y;
//返回值node
node operator +(const node &e) const{
return {e.x + x, e.y + y};
}
}f[N];
int main()
{
f[1].x = 2, f[1].y = 10;
f[2].x = 3, f[2].y = 11;
// +返回值node(结构体) 类型
f[3] = f[1] + f[2];
cout << f[3].x << " " << f[3].y<<endl;
return 0;
}

点击并拖拽以移动

输出结果:5 21

解释: (2+3)(10+11)

2、重载<(小于号),定义结构体排序规则

结构体的排序,就是用<来进行比较大小。因此只要重载运算符<即可自定义排序规则。

\1. 按x从大到小排序,x相同时按y从小到大排序

运算符重载实现

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
#include<bits/stdc++.h>
using namespace std;
const int N = 1000010;
struct node{
int x, y;
//用于比较大小返回值bool
bool operator < (const node &e) const{
if(e.x != x) return x > e.x;
return y < e.y;
}
}f[N];
int main()
{
srand(time(0));
cout << "排序前: " << endl;
for(int i = 1; i <= 5; i++)
{
// 生成0-9随机数
f[i].x = rand() % 10; f[i].y = i;
cout << f[i].x << " " << f[i].y << endl;
}
// 排序下标从1开始到5
sort(f + 1, f + 1 + 5);
cout << "排序后: "<<endl;
for(int i = 1; i <= 5; i++)
cout << f[i].x << " " << f[i].y << endl;
return 0;
}

点击并拖拽以移动

排序前:
5 1
4 2
4 3
0 4
7 5
排序后:
7 5
5 1
4 2
4 3
0 4

sort传入比较函数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
#include<bits/stdc++.h>
using namespace std;
const int N = 1000010;
struct node{
int x, y;
}f[N];
bool cmp(node a, node b){
if(a.x != b.x) return a.x > b.x;
return a.y > b.y;
}
int main()
{
srand(time(0));
cout << "排序前: " << endl;
for(int i = 1; i <= 5; i++)
{
// 生成0-9随机数
f[i].x = rand() % 10; f[i].y = i;
cout << f[i].x << " " << f[i].y << endl;
}
sort(f + 1, f + 1 + 5, cmp);
cout << "排序后: "<<endl;
for(int i = 1; i <= 5; i++)
cout << f[i].x << " " << f[i].y << endl;
return 0;
}

点击并拖拽以移动

排序前:
9 1
8 2
2 3
9 4
5 5
排序后:
9 4
9 1
8 2
5 5
2 3

3、重载<(小于号)map,set等容器自带排序规则

map容器中默认排序规则是按照键的大小从小到达排序,如果键值类型为字符串那么是按字符串字典序从小到大排序,那么键值类型为自己定义的结构体呢?答案是会报错,因为直接无法比较两个结构大小,这时就要自己定义了。

\1. 定义比较方式即重载<,使map能按照此方式比较结构体大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;
struct node{
int x, y;
bool operator<(const node &a) const {
if (x != a.x) return x < a.x;
return y < a.y;
}
};
int main()
{
map<node, int> mp;
mp[{3, 1}] = 1; mp[{2, 3}] = 2;
mp[{3, 2}] = 3; mp[{4, 3}] = 4;
mp[{1, 3}] = 5;
map<node, int>::iterator it = mp.begin();
while(it != mp.end())
{
cout << (*it).first.x << " " << (*it).first.y << endl;
it ++;
}
return 0;
}

点击并拖拽以移动

输出结果:

1 3
2 3
3 1
3 2
4 3

优先队列priority_queue也叫堆,set等等同样如此

这里补充一个pair<int, int> (int类型可以更改)函数,其中自带重载的小于号,按first值从小到大,first值相同按second值从小到大,算法竞赛常用hh


运算符重载函数operator的简单用法与常用案例
https://leaf-domain.gitee.io/2024/03/08/ac_operator/
作者
叶域
发布于
2024年3月8日
许可协议