C++中对象比较需通过运算符重载实现,支持成员函数或全局友元函数形式,C++20引入的可自动生成比较操作,提升代码简洁性与一致性。

在C++中,对象之间的比较需要通过运算符重载来实现。默认情况下,类对象不能直接使用
==、
!=、
<等比较运算符,除非我们显式定义这些行为。通过重载这些运算符,可以让自定义类型像基本类型一样进行比较和操作。
运算符重载的基本概念
运算符重载允许我们为类类型定义特定运算符的行为。可以重载的比较运算符包括:
==、
!=、
<、
>、
<=、
>=。重载方式有两种:作为类的成员函数或作为全局函数(通常声明为友元)。
以一个简单的
Point类为例:
class Point {
public:
int x, y;
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 成员函数形式重载 ==
bool operator==(const Point& other) const {
return x == other.x && y == other.y;
}
// 成员函数形式重载 !=
bool operator!=(const Point& other) const {
return !(*this == other);
}
};
成员函数的左侧操作数是
*this,右侧是参数。这种方式适用于大多数二元运算符。
立即学习“C++免费学习笔记(深入)”;
全局函数重载与友元
某些情况下,比如希望支持隐式类型转换或对称操作(如
int + Point),更适合使用全局函数。对于访问私有成员的情况,可将全局函数声明为友元。
class Point {
private:
int x, y;
public:
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 声明友元函数
friend bool operator<(const Point& a, const Point& b);
friend bool operator==(const Point& a, const Point& b);
};
// 全局实现
bool operator<(const Point& a, const Point& b) {
if (a.x != b.x) return a.x < b.x;
return a.y < b.y;
}
bool operator==(const Point& a, const Point& b) {
return a.x == b.x && a.y == b.y;
}
bool operator!=(const Point& a, const Point& b) {
return !(a == b);
}
这种写法更灵活,尤其在需要对称参数类型时更自然。
三向比较(C++20)
C++20引入了三向比较运算符
<=>,也叫“太空船运算符”,可以简化比较逻辑。编译器能根据
<=>自动生成
==、
!=、
<等。
#includeclass Point { public: int x, y; Point(int x = 0, int y = 0) : x(x), y(y) {} auto operator<=>(const Point&) const = default; };
使用
= default让编译器自动生成比较逻辑。如果需要自定义,也可以手动实现:
auto operator<=>(const Point& other) const {
if (auto cmp = x <=> other.x; cmp != 0)
return cmp;
return y <=> other.y;
}
返回类型为
std::strong_ordering,支持完整的比较操作。
常见注意事项
- 保持语义一致:比如
==
应满足自反、对称、传递性 - 尽量使用
const
修饰函数和参数,避免意外修改 - 成对重载:定义
==
时也定义!=
,定义<
时考虑其他关系 - 避免过度重载:只重载逻辑清晰、有意义的运算符
基本上就这些。合理使用运算符重载能让类的使用更直观,尤其是配合STL容器(如
std::set、
std::map)时,
<或
<=>是必需的。C++20的三向比较大大简化了代码,推荐新项目使用。










