结构体重载运算符
友元函数方式
传两个参数,需要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;
}
- 第一个 const :代表返回值是常量无法被修改。
- 这时候把它去掉,
(n + m) = {1, 1};的写法是合法的。
- 这时候把它去掉,
- 第二个 const :代表传入的参数可以是常量,相当于允许常量参数的传入。
- 这时候如果把它去掉,由于参数 m 是一个常量,无法传入导致报错。
- 第三个 const :代表调用函数的可以是一个常量,同第二个。
- 这个时候把它去掉,由于调用函数的 n 是一个常量,因此会报错。
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;
这里是重载了 () 符号,相当于函数调用。