为了总结熟悉类与对象相关的语法,本文通过实现经典的日期计算来练习巩固这一块的知识
目录
一、要实现的功能
二、难点分析
2.1 判断日期大小
2.2 日期加/减对应天数
2.3 两个日期相减
三、源代码
牛客网日期类相关练习题:
日期累加_牛客题霸_牛客网
打印日期_牛客题霸_牛客网
日期差值_牛客题霸_牛客网
计算日期到天数转换_牛客题霸_牛客网
一、要实现的功能
#pragma once
#include<assert.h>
#include<iostream>using namespace std;class Date
{//流运算符重载friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
public:// 获取某年某月的天数int GetMonthDay(int year, int month);//检查日期是否合法bool CheckDate();//打印日期void print();// 全缺省的构造函数Date(int year = 2005, int month = 6, int day = 8);// 拷贝构造函数Date(const Date& d);// 赋值运算符重载Date& operator=(const Date& d);// 日期+=天数Date& operator+=(int day);// 日期+天数Date operator+(int day);// 日期-天数Date& operator-=(int day);// 日期-=天数Date operator-(int day);// 前置++Date& operator++();// 后置++Date operator++(int);// 前置--Date& operator--();// 后置--Date operator--(int);// >运算符重载bool operator>(const Date& d);// ==运算符重载bool operator==(const Date& d);// >=运算符重载bool operator >= (const Date& d);// <运算符重载bool operator < (const Date& d);// <=运算符重载bool operator <= (const Date& d);// !=运算符重载bool operator != (const Date& d);// 日期-日期 返回天数int operator-(const Date& d);private:int _year;int _month;int _day;};
二、难点分析
2.1 判断日期大小
与一般判断大小不同。日期判断先判断年再判断月。当年月相等时才判断天。
所以采用多个if逻辑来判断
2.2 日期加/减对应天数
先把天数全部在变量天上。再模拟人为计算进位的逻辑。
采用循环的逻辑
加天数:
- 循环结束条件即为,直到天数小于当前月对应的最大天数
- 循环体为:向月进位,月++,天减去前月对应的天数;
- 处理特殊情况:月超过了13,年进位,月变成1月
Date& Date::operator+=(int day) {_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;if (_month == 13){++_year;_month = 1;}}return *this; }
减天数:
- 循环结束条件即为,直到天数大于0
- 循环体为:向月借数,月--,天加上上一个月对应的天数;
- 处理特殊情况:月小于1,年--,月变成12月
Date& Date::operator-=(int day) {_day += day;while (_day <= 0){--_month;if (_month == 0){_month = 12;--_year;}_day += GetMonthDay(_year, _month);}return *this; }
2.3 两个日期相减
模拟人为运算的方法十分繁琐。不妨利用计算机擅长迭代循环计算的特性,采用穷举的方法,计算出两个日期相差多少天。
int Date::operator-(const Date& d)
{//符号位int flag = 1;//假设法Date max = *this;Date min = d;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;//穷举while (min != max){++min;++n;}return n * flag;
}
三、源代码
#include"Date.h"//流运算符重载
ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "-" << d._month << "-" << d._day << " " << endl;return out;
}
istream& operator>>(istream& in, Date& d)
{cout << "请依次输入年月日";in >> d._year >> d._month >> d._day;if (!d.CheckDate()){cout << " ⽇期⾮法" << endl;}return in;
}// 获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{assert(month > 0 && month < 13);static int std[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 &&( (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}else{return std[month];}
}
//检查日期是否合法
bool Date::CheckDate()
{if(_month < 1 || _month > 12|| _day < 1 || _day > GetMonthDay(_year, _month)){return false;}else{return true;}
}
void Date::print()
{cout << _year << "-" << _month << "-" << _day << " " << endl;
}
// 全缺省的构造函数
Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;if (!CheckDate()){cout << "日期非法" << endl;print();}
}
// 拷贝构造函数
Date::Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}
// 赋值运算符重载
Date& Date::operator=(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;return *this;
}// 日期+=天数
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;if (_month == 13){++_year;_month = 1;}}return *this;
}
// 日期+天数
Date Date::operator+(int day)
{Date tmp = *this;tmp += day;return tmp;
}// 日期-天数
Date& Date::operator-=(int day)
{_day += day;while (_day <= 0){--_month;if (_month == 0){_month = 12;--_year;}_day += GetMonthDay(_year, _month);}return *this;
}
// 日期-=天数
Date Date::operator-(int day)
{Date tmp = *this;tmp -= day;return tmp;
}// 前置++
Date& Date::operator++()
{*this += 1;return *this;
}
// 后置++
Date Date::operator++(int)
{Date tmp = *this;tmp += 1;return tmp;
}
// 前置--
Date& Date::operator--()
{*this += 1;return *this;
}
// 后置--
Date Date::operator--(int)
{Date tmp = *this;tmp -= 1;return tmp;
}// >运算符重载
bool Date::operator>(const Date& d)
{if (_year > d._year){return true;}else if (_year == d._year){if (_month > d._month){return true;}else if (_month == d._month){return _day > d._day;}}return false;
}
// ==运算符重载
bool Date::operator==(const Date& d)
{return _year == d._year && _month == d._month && _day == d._day;
}
// >=运算符重载
bool Date::operator >= (const Date& d)
{return *this > d || *this == d;
}
// <运算符重载
bool Date::operator < (const Date& d)
{return !(*this > d);
}
// <=运算符重载
bool Date::operator <= (const Date& d)
{return *this < d || *this == d;
}
// !=运算符重载
bool Date::operator != (const Date& d)
{return !(*this == d);
}// 日期-日期 返回天数
int Date::operator-(const Date& d)
{Date max = *this;Date min = d;int flag = 1;//假设法if (*this < d){max = d;min = *this;flag = -1;}int n = 0;//循环法while (min != max){++min;++n;}return n * flag;
}