C++中的运算符重载

在C++中,函数重载有两种方式:

  • 直接在类内部声明,只需要一个参数
    bool operator ==(const Node &node) {
        return this->x == node.x and this->y == node.y;
    }
  • 在类外部声明,需要两个参数
bool operator<(const Node &a, const Node &b) {
    if (a.x != b.x)return a.x < b.x;
    else return a.y < b.y;
}

除了手动重载这些函数,还可以使用模板函数进行快速重载,就像C#中的扩展方法和Go里面的struct一样给class插上“翅膀”。方法是:使用utility中的rel_ops命名空间。
这个命名空间实现了以下模板函数:

namespace rel_ops {
  template <class T> bool operator!= (const T& x, const T& y);
  template <class T> bool operator>  (const T& x, const T& y);
  template <class T> bool operator<= (const T& x, const T& y);
  template <class T> bool operator>= (const T& x, const T& y);
}

如上所示,rel_ops命名空间实现了四种运算符,我们只需要自己实现==<两个运算符就能够实现以上四种运算符了。

请看一个完整的例子。

#include<iostream>
#include<iso646.h>
using namespace std;
class Node {
public:
    int x, y;
    Node(int x, int y) {
        this->x = x, this->y = y;
    }
    bool operator ==(const Node &node) {
        return this->x == node.x and this->y == node.y;
    }
};
bool operator<(const Node &a, const Node &b) {
    if (a.x != b.x)return a.x < b.x;
    else return a.y < b.y;
}
int main() {
    using namespace std::rel_ops;
    Node m(3, 4), n(2, 5);
    cout << (m > n) << endl;
    cout << (m <= n) << endl;
    return 0;
}

还有一个关键之处:左移运算符和移位运算符都是<<,但是因为它们接受的参数不一样,所以可以同时重载。

#include <iostream>
using namespace::std;
class MyClass
{
public:
    MyClass(int a, int b)
    {
        this->a = a;
        this->b = b;
    }
    void print_Myclass() {
        cout << this->a << '+' << b << 'i' << endl;
    }
    //输出运算符和左移运算符虽然样子一样,但是参数不一样,所以相当于运算符重载
    friend ostream & operator<<(ostream &os, MyClass &c);
    MyClass operator<<(int cnt) {
        return MyClass(a << cnt, b << cnt);
    }
private:
    int a;
    int b;
};

//使用友元访问私有变量
ostream & operator<<(ostream &os, MyClass &c) {
    os << c.a << '+' << c.b << 'i';
    return os;
}
void main() {
    MyClass c(3, 4);
    cout << c << endl;
    MyClass cc = c << 1;
    cout << cc << endl;
    //下面这句话会报错,因为cc<<1返回来的对象是一个临时对象,而cout<<需要的参数却是MyClass&类型的对象
    //cout << (cc << 1) << endl;
}

虽然移位运算符正常情况下接受的参数是int,表示移位的个数,但实际上这个参数可以是任何类型,移位运算符完全由用户掌控,但是有两点需要注意:

  • 运算符的参数个数必须一致
  • 重载运算符后的优先级和结合性都不会改变。
    MyClass operator<<(double cnt) {
        return MyClass(a * cnt, b *cnt);
    }

C++中可以重载的运算符包括

+   -   *   /   %   ^   &   |   ~

!   =   <   >   +=  -=  *=  /=  %

^=  &=  |=  <<  >>  >>= <<= ==  !=

<=  >=  &&  ||  ++  --  ->* ‘   ->

[]  ()  new delete  new[]   delete[]

不能重载的操作符是类属关系运算符 如:

.   ::   .* ?:  sizeof
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值