使用成员布尔函数比较对象数组数据的问题排查
问题描述
需要用Person类的operator==成员函数比较对象数组中人员的出生日期,同时利用operator<成员函数找出出生日期最早的人员,但程序仅输出数组内容后便退出,无法实现预期功能,尝试编写operator<逻辑未成功,附上代码:
#include <iostream> #include <string> using namespace std; class Birth_date { private: unsigned int day{}; unsigned int month{}; unsigned int year{}; public: Birth_date() {} Birth_date(int day, int month, int year) { this->day = day; this->month = month; this->year = year; } Birth_date(const Birth_date& birth) { day = birth.day; month = birth.month; year = birth.year; } void set_day(int day) { this->day = day; } void set_month(int month) { this->month = month; } void set_year(int year) { this->year = year; } int get_day() { return day; } int get_month() { return month; } int get_year() { return year; } friend bool operator == (const Birth_date& a, const Birth_date& b) { return (a == b); } bool operator < (const Birth_date& bd) { return day < bd.day && month < bd.month && year < bd.year; } bool operator > (const Birth_date& bd) { return day > bd.day && month > bd.month && year > bd.year; } ostream& Output(ostream& out) { out << "Date of birth: " << day << "/" << month << "/" << year << endl; return out; } }; class Person { private: string name; Birth_date dob; public: Person() {} Person(string name, Birth_date dob) { this->name = name; this->dob = dob; } Person(const Person& p) { name = p.name; dob = p.dob; } string get_name() { return name; } Birth_date get_dob() { return dob; } bool operator < (const Person& p)const { Birth_date bd1 = p.dob; Birth_date bd2 = p.dob; return (bd1 < bd2); } bool operator == (const Person& p)const { return (dob == p.dob); } const ostream& output(ostream& out) { out << "Name: " << name << "\t" ; dob.Output(out); return out; } }; int main() { Person students[5] = { Person("Ivan Petkov",Birth_date(10,6,1999)), Person("Gabe Trent",Birth_date(20,12,1996)), Person("Maggy Sommer",Birth_date(5,2,2000)), Person("Cameron Dallas",Birth_date(1,4,2001)), Person("Catherine Crumb",Birth_date(28,8,2000)) }; for (int i = 0; i < 5; i++) { students[i].output(cout); } cout << "\n"; for (int i = 0; i < 5; i++) { for (int x = i + 1; x < 5; x++) { if (students[i].operator==(students[x])) { cout << "Students " << students[i].get_name() << "and " << students[x].get_name() << "have the same date of birth." << endl; } else cout << "Nobody has the same date of birth." << endl; } } return 0; }
问题分析与修复
1. Birth_date类operator==递归死循环
原代码中operator==直接返回a == b,会无限递归调用自身,导致程序崩溃。正确实现应该逐一比较年、月、日:
friend bool operator == (const Birth_date& a, const Birth_date& b) { return (a.year == b.year && a.month == b.month && a.day == b.day); }
2. Birth_date类operator<逻辑错误
原代码用&&连接年月日的比较,只有当前对象的年、月、日全部小于另一个对象时才返回true,这不符合日期比较逻辑。正确逻辑是先比年份,年份小则日期更早;年份相同比月份,月份小则更早;月份相同比日期:
bool operator < (const Birth_date& bd) const // 加上const保证常量对象可调用 { if (year != bd.year) return year < bd.year; if (month != bd.month) return month < bd.month; return day < bd.day; }
同时给函数加上const修饰,确保常量对象能调用该运算符。
3. Person类operator<逻辑错误
原代码中bd1和bd2都是p.dob,比较同一个对象永远返回false,正确应该比较当前对象的dob和参数p的dob:
bool operator < (const Person& p)const { return this->dob < p.dob; }
4. 主函数重复输出问题
原双重循环中,每对不相等的学生都会输出“Nobody has the same date of birth”,导致大量冗余输出。应该先标记是否找到相同出生日期的学生,循环结束后统一提示:
bool hasSameDob = false; for (int i = 0; i < 5; i++) { for (int x = i + 1; x < 5; x++) { if (students[i] == students[x]) // 直接用==运算符,无需显式调用operator== { cout << "Students " << students[i].get_name() << " and " << students[x].get_name() << " have the same date of birth." << endl; hasSameDob = true; } } } if (!hasSameDob) cout << "Nobody has the same date of birth." << endl;
5. 添加寻找最早出生日期的逻辑
遍历数组,用operator<找到最早的学生:
Person earliestStudent = students[0]; for (int i = 1; i < 5; i++) { if (students[i] < earliestStudent) { earliestStudent = students[i]; } } cout << "\nStudent with earliest date of birth:" << endl; earliestStudent.output(cout);
修复后的完整代码
#include <iostream> #include <string> using namespace std; class Birth_date { private: unsigned int day{}; unsigned int month{}; unsigned int year{}; public: Birth_date() {} Birth_date(int day, int month, int year) : day(static_cast<unsigned int>(day)), month(static_cast<unsigned int>(month)), year(static_cast<unsigned int>(year)) {} Birth_date(const Birth_date& birth) : day(birth.day), month(birth.month), year(birth.year) {} void set_day(int day) { this->day = static_cast<unsigned int>(day); } void set_month(int month) { this->month = static_cast<unsigned int>(month); } void set_year(int year) { this->year = static_cast<unsigned int>(year); } unsigned int get_day() const { return day; } unsigned int get_month() const { return month; } unsigned int get_year() const { return year; } friend bool operator == (const Birth_date& a, const Birth_date& b) { return (a.year == b.year && a.month == b.month && a.day == b.day); } bool operator < (const Birth_date& bd) const { if (year != bd.year) return year < bd.year; if (month != bd.month) return month < bd.month; return day < bd.day; } bool operator > (const Birth_date& bd) const { return bd < *this; } ostream& Output(ostream& out) const { out << "Date of birth: " << day << "/" << month << "/" << year; return out; } }; class Person { private: string name; Birth_date dob; public: Person() {} Person(string name, Birth_date dob) : name(move(name)), dob(dob) {} Person(const Person& p) : name(p.name), dob(p.dob) {} string get_name() const { return name; } Birth_date get_dob() const { return dob; } bool operator < (const Person& p) const { return dob < p.dob; } bool operator == (const Person& p) const { return dob == p.dob; } ostream& output(ostream& out) const { out << "Name: " << name << "\t"; dob.Output(out); out << endl; return out; } }; int main() { Person students[5] = { Person("Ivan Petkov", Birth_date(10,6,1999)), Person("Gabe Trent", Birth_date(20,12,1996)), Person("Maggy Sommer", Birth_date(5,2,2000)), Person("Cameron Dallas", Birth_date(1,4,2001)), Person("Catherine Crumb", Birth_date(28,8,2000)) }; cout << "All students:" << endl; for (const auto& student : students) { student.output(cout); } cout << "\nChecking for same date of birth:" << endl; bool hasSameDob = false; for (int i = 0; i < 5; i++) { for (int x = i + 1; x < 5; x++) { if (students[i] == students[x]) { cout << "Students " << students[i].get_name() << " and " << students[x].get_name() << " have the same date of birth." << endl; hasSameDob = true; } } } if (!hasSameDob) cout << "Nobody has the same date of birth." << endl; cout << "\nStudent with earliest date of birth:" << endl; Person earliestStudent = students[0]; for (int i = 1; i < 5; i++) { if (students[i] < earliestStudent) { earliestStudent = students[i]; } } earliestStudent.output(cout); return 0; }
内容的提问来源于stack exchange,提问作者Heiru
相关产品推荐
相关产品推荐

