C++ 黑科技——重载运算符!
RiverFun
2018-10-20 13:47:18
重载运算符是用来~~装逼~~简化程序的绝佳利器!
重载运算符的功能就是重新定义运算符来实现不同的功能
让我们先举个栗子:
![](https://cdn.luogu.com.cn/upload/pic/38716.png)
```cpp
bool operator < (node a , node b) {
return a.w > b.w;
}
```
熟悉优先队列STL的人都知道,`priority_queue`默认大根堆,但如果我们想把他直接用去优化dijkstra肯定是不行的,所以我们可以以上的一段代码加入来将`priority_queue`变为小根堆,定义优先队列这样写`priority_queue <node> q`就行了
当然,你也可以将重载运算符写在`sruct`里:
```cpp
struct node {
int id , w;
bool operator < (const node &b) const {
return w > b.w;
}
}
```
如果你不使用重载运算符的话,就得这么写:
```cpp
struct node {
int id , w;
}
struct cmp {
bool operator ()(node a , node b) {
return a.w > b.w;
}
priority_queue <node , vector <node> , cmp> q;
```
看,多麻烦!~~(不过好像也复杂不到哪去)~~
下面又是一个例子(矩阵乘法&矩阵快速幂):
```cpp
Mat operator * (Mat a , Mat b) {
Mat c;
c.clear();
for (int i = 0 ; i < 2 ; i++) {
for (int j = 0 ; j < 2 ; j++) {
for (int k = 0 ; k < 2 ; k++) {
c.a[i][j] = (c.a[i][j] + (a.a[i][k] * b.a[k][j]) % MOD) % MOD;
}
}
}
return c;
}
Mat qpow(Mat a , ll n) {
Mat b;
b.init();
while (n) {
if (n & 1) b = b * a;
n >>= 1;
a = a * a;
}
return b;
}
```
显然,如果你直接定义一个名为`Mat`的结构体,然后再使用`Mat`定义两个变量,将这两个变量直接用`*`相乘,肯定会CE。
这个时候,重载运算符就登场了!
重载运算符重新定义两个`Mat`型变量的乘法,使它们**只按**这种规则进行运算,减少代码量。
是不是很神奇呢?~~(好像不是)~~
但是,使用重载运算符时要注意,**不能重新规定编译器所给的变量之间的运算**
比如下面这个例子:
```cpp
int operator + (int a , int b) {
return a - b;
}
```
强行将`int`型变量的加法操作定义为减法,这种方法不行,会CE。
~~我有一次就因为想省事把快速乘重载定义了一下然后CE了。。。~~
重载运算符可定义的常用操作符如下:
```
+ \\加
- \\减
* \\乘
/ \\除
% \\取模
+= \\自加
-= \\自减
*= \\自乘
/= \\自除
%= \\自模
^ \\异或
^= \\自异或
& \\与
&= \\自与
| \\或
|= \\自或
== \\判等
!= \\判不等
....
```
这就是神奇的重载运算符!