Skip to content
Ficon's Paper
Go back

重载运算符

结构体重载运算符

友元函数方式

传两个参数,需要friend定义

struct Point
{
	int x, y;
	friend bool operator < (Point a, Point b) {
        if(a.x == b.x)
            return a.y < b.y;
		return a.x < b.x;//按x从小到大排
	}
};

// or
bool operator < (Point a, Point b) {
	if(a.x == b.x)
		return a.y < b.y;
	return a.x < b.x;
}

友元函数本质上是全局函数,它可以在类中定义和实现,也可以在类中定义,在外部实现。

友元代表该函数可以访问结构体/对象的私有变量。

为什么 << 必须用友元?

因为 cout << obj 中,左操作数是 ostream,不是你的类,没法写成成员函数:

// 想写成成员函数?左操作数必须是 Circle,行不通
os << c;  // 左边是 ostream,不是 Circle

// 只能写成全局函数,但要访问私有成员,所以需要 friend
friend ostream& operator<<(ostream& os, const Circle& c);

成员函数方式

struct Point
{
    int x, y;
    bool operator<(const Point &a) const {
        if(x == a.x)
            return y < a.y;
        return x < a.x; //按x升序排列
    }
    // operator< 相当于函数名
};

这里 this 是作为第一个参数,符号后面的是传进来的第二个参数。

最后一个 const 用来修饰成员函数,表示不会修改调用它的对象 this,因为 c++ 中规定,const 对象只能调用 const 成员函数。

例如,对于这样一串代码:

#include<bits/stdc++.h>
using namespace std;

struct node
{
    int x, y;
    const node operator + (const node &a) const {
        return {x + a.x, y + a.y};
    }
};

int main()
{
    const node n = {3, 5};
    const node m = {1, 8};
    node ans = n + m;
    cout << ans.x << endl << ans.y << endl;
    return 0;
}

n + m 相当于 n.operator+(m)

All:

#include <bits/stdc++.h>
using namespace std;

struct node {
  int x, y;
  const node operator+(const node &a) const { return {x + a.x, y + a.y}; }
  const node operator-(const node &a) const { return {x - a.x, y - a.y}; }
  const node operator-() const { return {-x, -y}; }
  void operator+=(const node &a) {
    x += a.x;
    y += a.y;
  }
  void operator-=(const node &a) {
    x -= a.x;
    y -= a.y;
  }
  bool operator==(const node &a) const { return x == a.x && y == a.y; }
  bool operator!=(const node &a) const { return x != a.x || y != a.y; }
  void operator++() { // 前置
    ++x;
    ++y;
  }
  const node operator++(int) { // 后置
    node old = {x, y};
    x++;
    y++;
    return old;
  }
  void operator--() { // 前置
    --x;
    --y;
  }
  const node operator--(int) { // 后置
    node old = {x, y};
    x--;
    y--;
    return old;
  }
};

/*由于<<左侧必须是cout,因此不可作为成员函数进行重载,必须写在全局区,也可通过与友元函数相结合来实现目的*/
ostream &operator<<(ostream &out,
                    const node &a) { // 注意返回值为引用类型的输出流

  out << a.x << ' ' << a.y;
  return out;
}
istream &operator>>(istream &in, node &a) { // 由于是读入,所以参数不能为常量

  in >> a.x >> a.y;
  return in;
}

int main() {
  const node n = {3, 5};
  const node m = {1, 8};
  node ans = n + m;
  cout << ans.x << ' ' << ans.y << endl;
  ans = n - m;
  cout << ans.x << ' ' << ans.y << endl;
  ans = -ans;
  cout << ans.x << ' ' << ans.y << endl;
  ans += {10, 10};
  cout << ans.x << ' ' << ans.y << endl;
  ans -= {5, 5};
  cout << ans.x << ' ' << ans.y << endl;
  cout << (n == m) << ' ';
  cout << (n != m) << ' ';
  cout << ans++.x << ' ' << ans.y << endl;
  cout << ans--.x << ' ' << ans.y << ' ' << ans.x << endl;
  cout << ans << endl;
  node ano;
  cin >> ano;
  cout << ano << endl;
  return 0;
}

全局函数方式

函数排序规则

struct Point
{
    int x, y;
}p[1005];
bool cmp(Point a, Point b)
{
    if(a.x == b.x)
        return a.y < b.y;
    return a.x < b.x;
}
sort(p + 1, p + 1 + 1000, cmp);

堆排序规则

struct cmp { 
	bool operator()(const Point& a,const Point& b)
	{
        if(a.x == b.x)
            return a.y < b.y;
		return a.x < b.x;
	}
};

priority_queue<Point,vector<Point>, cmp> q; 

这里是重载了 () 符号,相当于函数调用。


Share this post on:

Previous Post
CF1765I
Next Post
Tricks