C++ 黑科技——重载运算符!
重载运算符是用来装逼简化程序的绝佳利器!
重载运算符的功能就是重新定义运算符来实现不同的功能
让我们先举个栗子:
bool operator < (node a , node b) {
return a.w > b.w;
}
熟悉优先队列STL的人都知道,priority_queue默认大根堆,但如果我们想把他直接用去优化dijkstra肯定是不行的,所以我们可以以上的一段代码加入来将priority_queue变为小根堆,定义优先队列这样写priority_queue <node> q就行了
当然,你也可以将重载运算符写在sruct里:
struct node {
int id , w;
bool operator < (const node &b) const {
return w > b.w;
}
}
如果你不使用重载运算符的话,就得这么写:
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;
看,多麻烦!(不过好像也复杂不到哪去)
下面又是一个例子(矩阵乘法&矩阵快速幂):
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型变量的乘法,使它们只按这种规则进行运算,减少代码量。
是不是很神奇呢?(好像不是)
但是,使用重载运算符时要注意,不能重新规定编译器所给的变量之间的运算
比如下面这个例子:
int operator + (int a , int b) {
return a - b;
}
强行将int型变量的加法操作定义为减法,这种方法不行,会CE。
我有一次就因为想省事把快速乘重载定义了一下然后CE了。。。
重载运算符可定义的常用操作符如下:
+ \\加
- \\减
* \\乘
/ \\除
% \\取模
+= \\自加
-= \\自减
*= \\自乘
/= \\自除
%= \\自模
^ \\异或
^= \\自异或
& \\与
&= \\自与
| \\或
|= \\自或
== \\判等
!= \\判不等
....
这就是神奇的重载运算符!