C++ 黑科技——重载运算符!

RiverFun

2018-10-20 13:47:18

Personal

重载运算符是用来~~装逼~~简化程序的绝佳利器! 重载运算符的功能就是重新定义运算符来实现不同的功能 让我们先举个栗子: ![](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了。。。~~ 重载运算符可定义的常用操作符如下: ``` + \\加 - \\减 * \\乘 / \\除 % \\取模 += \\自加 -= \\自减 *= \\自乘 /= \\自除 %= \\自模 ^ \\异或 ^= \\自异或 & \\与 &= \\自与 | \\或 |= \\自或 == \\判等 != \\判不等 .... ``` 这就是神奇的重载运算符!