Unverified Commit aa516828 authored by Shuhao Zhang's avatar Shuhao Zhang Committed by GitHub
Browse files

feat(op-overload): add code

parent 58bd6f97
Loading
Loading
Loading
Loading
+87 −1
Original line number Diff line number Diff line
@@ -25,6 +25,44 @@ C++ 自带的运算符,最初只定义了一些基本类型的运算规则。

函数调用运算符 `()` 只能重载为成员函数。通过对一个类重载 `()` 运算符,可以使该类的对象能像函数一样调用。

重载 `()` 运算符的一个常见应用是,将重载了 `()` 运算符的结构体作为自定义比较函数传入优先队列等 STL 容器中。

下面就是一个例子:给出 $n$ 个学生的姓名和分数,按分数降序排序,分数相同者按姓名字典序升序排序,输出排名最靠前的人的姓名和分数。

```cpp
#include <iostream>
#include <queue>
using namespace std;
struct student
{
 string name;
 int score;
};
struct cmp
{
 bool operator()(const student&a,const student&b)const
 {
  return a.score<b.score||(a.score==b.score&&a.name>b.name);
 }
};
priority_queue<student,vector<student>,cmp> pq;
int main()
{
 int n;
 cin>>n;
 for(int i=1;i<=n;i++)
 {
  string name;
  int score;
  cin>>name>>score;
  pq.push({name,score});
 }
 student rk1=pq.top();
 cout<<rk1.name<<' '<<rk1.score<<endl;
 return 0;
}
```

### 自增自减运算符<span id="incdec"></span>

自增自减运算符分为两类,前置和后置。为了能将两类运算符区别开来,对于后置自增自减运算符,重载的时候需要添加一个类型为 `int` 的空置形参。
@@ -42,4 +80,52 @@ C++ 自带的运算符,最初只定义了一些基本类型的运算规则。

`std::sort` 和一些 STL 容器中,需要用到 `<` 运算符。在使用自定义类型时,我们需要手动重载。

重载了 `<` 运算符后,我们可以利用 `<` 运算符,重载其他五个比较运算符。
还是以讲函数调用运算符时举的例子说起,如果我们重载比较运算符,实现代码是这样的:

```cpp
#include <iostream>
#include <queue>
using namespace std;
struct student
{
 string name;
 int score;
 bool operator<(const student&a)const
 {
  return score<a.score||(score==a.score&&name>a.name);
  // 上面省略了 this 指针,完整表达式如下:
  // this->score<a.score||(this->score==a.score&&this->name>a.name);
 }
};
priority_queue<student> pq;
int main()
{
 int n;
 cin>>n;
 for(int i=1;i<=n;i++)
 {
  string name;
  int score;
  cin>>name>>score;
  pq.push({name,score});
 }
 student rk1=pq.top();
 cout<<rk1.name<<' '<<rk1.score<<endl;
 return 0;
}
```

事实上,只要有了 `<` 运算符,则其他五个比较运算符的重载也可以很容易实现。

```cpp
bool operator< (const T& lhs, const T& rhs){ /* 这里重载小于运算符 */ }
bool operator> (const T& lhs, const T& rhs){ return rhs < lhs; }
bool operator<=(const T& lhs, const T& rhs){ return !(lhs > rhs); }
bool operator>=(const T& lhs, const T& rhs){ return !(lhs < rhs); }
bool operator==(const T& lhs, const T& rhs){ return !(lhs < rhs)&&!(lhs > rhs); }
bool operator!=(const T& lhs, const T& rhs){ return !(lhs == rhs); }
```

参考资料与注释:

- [运算符重载 - cppreference](https://zh.cppreference.com/w/cpp/language/operators)