比较运算符重载
本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 42 课,共 104 课。
像 ==、!=、<、>、<= 和 >= 这样的比较运算符,可以比较自定义类的对象。这些运算符会返回 bool,并且应标记为 const,因为它们不会修改任一操作数。
class Date {
int year, month, day;
public:
Date(int y, int m, int d) : year(y), month(m), day(d) {}
bool operator==(const Date& other) const {
return year == other.year &&
month == other.month &&
day == other.day;
}
bool operator<(const Date& other) const {
if (year != other.year) return year < other.year;
if (month != other.month) return month < other.month;
return day < other.day;
}
};一种实用的方法是基于你已经定义的比较运算符来实现其他比较运算符。一旦有了 == 和 <,其余的运算符就能自然地推导出来:
bool operator!=(const Date& other) const {
return !(*this == other);
}
bool operator>(const Date& other) const {
return other < *this;
}
bool operator<=(const Date& other) const {
return !(other < *this);
}
bool operator>=(const Date& other) const {
return !(*this < other);
}这种做法可以减少代码重复,并确保所有比较运算符的行为保持一致。如果你之后修改相等或小于的判断方式,其他运算符也会自动保持同步。
挑战
简单让我们创建一个 Version 类,用来表示软件版本号(例如 2.1.0 或 3.0.5),并支持全部六种比较运算符。比较版本号可以判断哪个软件更新,这是一个实用的场景,也很适合练习比较运算符重载。
你需要创建两个文件来组织代码:
Version.h:定义一个Version类,用三个整数分别存储主版本号、次版本号和修订版本号。你的类应支持:- 一个接收主版本号、次版本号和修订版本号的构造函数
- 用于获取各个部分的 getter:
getMajor()、getMinor()、getPatch()(均为 const) - 全部六种比较运算符:
==、!=、<、>、<=、>= - 一个
toString()方法,以"major.minor.patch"的格式返回表示版本号的字符串
直接实现
==和<,然后基于这两个运算符定义其余四种运算符。进行小于比较时,先比较主版本号;如果主版本号相同,再比较次版本号;如果主版本号和次版本号都相同,则比较修订版本号。所有比较运算符都应是 const 成员函数。main.cpp:从输入中读取六个整数,表示两个版本号(每行一个,依次为 major1、minor1、patch1、major2、minor2、patch2)。创建两个Version对象,并使用你实现的所有运算符进行比较。输出格式:
Version 1: <v1> Version 2: <v2> v1 == v2: <true/false> v1 != v2: <true/false> v1 < v2: <true/false> v1 > v2: <true/false> v1 <= v2: <true/false> v1 >= v2: <true/false>每个比较结果都输出小写的
true或false。
这里的关键技巧是只使用 == 和 < 来实现另外四种派生运算符(!=、>、<=、>=)。这样可以减少重复代码,并确保以后修改比较逻辑时,所有运算符的行为保持一致。
使用 std::stoi() 将输入字符串转换为整数。使用 std::to_string() 拼接版本号字符串。别忘了在头文件中添加头文件保护。
亲手试试
#include <iostream>
#include <string>
#include "Version.h"
using namespace std;
int main() {
// 读取两个版本对应的 6 个整数
string line;
getline(cin, line);
int major1 = stoi(line);
getline(cin, line);
int minor1 = stoi(line);
getline(cin, line);
int patch1 = stoi(line);
getline(cin, line);
int major2 = stoi(line);
getline(cin, line);
int minor2 = stoi(line);
getline(cin, line);
int patch2 = stoi(line);
// TODO: 创建两个 Version 对象
// TODO: 使用 toString() 输出 Version 1 和 Version 2
// TODO: 使用全部 6 个运算符进行比较并输出结果
// 每次比较都使用 "true" 或 "false"(小写)
// 格式:"v1 == v2: true" 或 "v1 == v2: false"
return 0;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C++ 在线编译器