(八) 运算符重载与比较规则
整数已有加法与大小比较。给自定义坐标实现同样的操作时,可以把加法写成横、纵坐标分别相加,把大小比较写成先比较横坐标、再比较纵坐标。
运算符重载让自定义类型支持自然的操作。例如坐标点相加:
比较规则要让等价和先后关系保持一致。 下面的点先比较 x,x 相同再比较 y,相当于按 (x,y) 的字典序排列。例如 (1,9) < (2,0),而 (1,3) < (1,9)。两点都为 (1,3) 时,两个方向的比较都为 false。
沿这个字典序,若 a 排在 b 前、b 排在 c 前,就能推出 a 排在 c 前;两个方向都不排在前面的点则视为等价。这样的先后与等价关系称为严格弱序。比较学生成绩时,也可以先按成绩,再按编号决定同分记录的次序。operator+ 则把横、纵坐标分别相加,返回一个新点。
// 加法逐坐标计算;小于比较采用字典序,保证严格弱序。
struct Point {
long long x;
long long y;
Point operator+(const Point &other) const {
return {x + other.x, y + other.y};
}
bool operator<(const Point &other) const {
if (x != other.x) {
return x < other.x;
}
return y < other.y;
}
};在 sort 中,比较函数回答“a 是否排在 b 前”。a 与自身比较时,答案是 false;若写成 a<=b,相等时会得到 true,与这个含义相反。上面的字典序使用 <,两字段都相等时自然返回 false。
对 set 来说,“两个方向比较都为 false”的元素视为等价。如果仅按成绩比较,同分学生可能被当成同一个元素;需要保留他们时,可以再按姓名或唯一编号比较。参见 C++ 标准草案:关联容器要求。