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了。。。

重载运算符可定义的常用操作符如下:

+ \\加
- \\减
* \\乘
/ \\除
% \\取模
+= \\自加
-= \\自减
*= \\自乘
/= \\自除
%= \\自模
^ \\异或
^= \\自异或
& \\与
&= \\自与
| \\或
|= \\自或
== \\判等
!= \\判不等
....

这就是神奇的重载运算符!