目录
1.1已知年月获取天数函数 int getday(int year, int month) const
主要实现了对日期的操作,包括日期的比较,日期-日期,日期+天数,日期++,++日期,日期,--日期,以及对日期中>> 和 << 的重载。
1.data.h文件
采用了声明与定义分离。
#pragma once
#include<iostream>
#include<algorithm>
#include<assert.h>
using namespace std;
class Data {
//友元函数声明
friend ostream& operator<<(ostream& out, const Data& d);
friend istream& operator>>(istream& in, Data& d);
public:
Data(int year = 1900, int month = 1, int day = 1);//构造函数
bool CheckDate()const;
void Print()const;
int getday(int year, int month) const
{
assert(month > 0 && month < 13);
static int monthDayArray[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;
}
return monthDayArray[month];
}
bool operator<(const Data& d) const;
bool operator<=(const Data& d) const;
bool operator>(const Data& d) const;
bool operator>=(const Data& d) const;
bool operator==(const Data& d) const;
bool operator!=(const Data& d) const;
Data operator+(int day) const;
Data& operator+=(int day);
Data operator-(int day) const;
Data& operator-=(int day);
Data operator++(int);
Data& operator++();
Data operator--(int);
Data& operator--();
int operator-(const Data& d) const;
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& out, const Data& d);
istream& operator>>(istream& in, Data& d);
1.1已知年月获取天数函数 int getday(int year, int month) const
int getday(int year, int month) const
{
assert(month > 0 && month < 13);
static int monthDayArray[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;
}
return monthDayArray[month];
}
(1).我们直接将数组下标1到12设置为每月的天数,特判当时2月且时闰年时,我们返回29即可。
2.函数的实现
2.1构造函数
Data::Data(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
if (!CheckDate())
{
cout << "非法日期:";
Print();
}
}
(1).简单的构造函数的实现,要判断一下当前日期是否合法。
2.2检查日期合法函数
bool Data::CheckDate()const
{
if (_month <= 0 || _month > 12 || _day<1 || _day>getday(_year, _month)) {
return false;
}
return true;
}
(1).当月小于等于0,或者月大于12,或者天小于1,或者天大于该月的总天数,则返回fallse,其余情况返回true。
2.3日期类重载小于号(<)
bool Data::operator<(const Data& d) const
{
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;
}
(1).先判断年,若年小于则返回true即可,如果等于时,在判断月,如果月小于,则返回true,若月等于时,则判断天,直接判断 _day < d._day 是否成立即可。最后返回false。
2.4日期类重载等于号(==)
bool Data::operator==(const Data& d) const
{
return _year == d._year && _month == d._month && _day == d._day;
}
(1).直接判断 _year == d._year && _month == d._month && _day == d._day 是否成立即可。
2.5日期类重载小于等于号(<=)
bool Data::operator<=(const Data& d) const
{
return *this < d || *this == d;
}
(1).由于我们之前以及重载<以及==号,所以我们直接利用即可,当<成立或者==成立时,返回true。
2.6日期类重载大于号(>)
bool Data::operator>(const Data& d) const
{
return !(*this <= d);
}
(1).我们之前重载了<=号,所以我们直接!(*this <= d)即可。
2.7重载大于等于号(>=)
bool Data::operator>=(const Data& d) const {
return *this > d || *this == d;
}
(1).我们之前重载了>号和==号,如果>号成立或者==号成立,则返回true。
2.8重载不等于号(!=)
bool Data::operator!=(const Data& d) const
{
return !(*this == d);
}
(1).已经实现了重载等于号(==),直接判断 !(*this == d) 即可。
2.9重载加等于号(+=)
Data& Data::operator+=(int day) {
if (day < 0) {
return *this -= (-day);
}
_day += day;
while (_day > Data::getday(_year, _month))
{
_day -= getday(_year, _month);
_month++;
if (_month > 12) {
_month = 1;
_year++;
}
}
return *this;
}
(1).首先要判断day是否为负,日期+(负数)相当于日期-天数,如果day小于0,则我们利用减等于号(-=)。
(2).首先让当前天数加上day,然后循环判断_day是否大于当前月的总天数,如果大于就先减去当前月的总天数,然后将月加一,要特判月大于12时,月要归1,年要加一。
(3).最后返回当前*this指针,因为是+=,是对自身加。
2.10重载减等于号(-=)
Data& Data::operator-=(int day) {
if (day < 0) {
return *this += (-day);
}
_day -= day;
while (_day <= 0) {
_month--;
if (_month == 0) {
_month = 12;
_year--;
}
_day += getday(_year, _month);
}
return *this;
}
(1).首先要判断day是否为负,日期-(负数)相当于日期+天数,如果day小于0,则我们利用加等于号(+=)。
(2).首先让当前天数减去day,然后循环判断_day是否小于等于0,如果小于等于0就先将月减一,然后加上当前月的总天数,要特判月等于0时,月要置为12,年要减一。
(3).最后返回当前*this指针,因为是-=,是对自身减。
2.11重载加号(+)(日期+天数)
Data Data::operator+(int day) const {
Data temp = *this;
temp += day;
return temp;
}
(1).因为是+号,并不是+=,没有对自身加,所以我们创建一个Data类,复制*this,然后我们使用重载+=,对temp自身加,然后返回temp即可。
2.12重载减号(-)(日期-天数)
Data Data:: operator-(int day) const
{
Data temp = *this;
temp -= day;
return temp;
}
(1).因为是-号,并不是-=,没有对自身减,所以我们创建一个Data类,复制*this,然后我们使用重载-=,对temp自身减,然后返回temp即可。
2.13重载后置加加(后置++)
Data Data::operator++(int)
{
Data temp = *this;
temp += 1;
return temp;
}
(1).后置++和前置++的区别为,在传参时,后置++要加上一个int。
(2).因为是后置++,所以是后赋值,我们创建一个Data类,对这个类+=1即可,最后返回temp。
2.14重载前置加加(++前置)
Data& Data::operator++()
{
*this += 1;
return *this;
}
(1).因为是前置加加,所以是先自加然后再赋值,就要先改变自身,所以直接对*this+=1即可。
2.15重载后置减减(后置--)
Data Data:: operator--(int)
{
Data temp = *this;
temp -= 1;
return temp;
}
(1).后置--和前置--的区别为,在传参时,后置--要加上一个int。
(2).因为是后置--,所以是后赋值,我们创建一个Data类,对这个类-=1即可,最后返回temp。
2.16重载前置减减(--前置)
Data& Data::operator--()
{
*this -= 1;
return *this;
}
(1).因为是前置减减,所以是先自减然后再赋值,就要先改变自身,所以直接对*this-=1即可。
2.17重载减号(-)(日期-日期)
int Data::operator-(const Data& d) const {
int ans = 0;
Data temp1 = *this;
Data temp2 = d;
if (temp2 > temp1) {
swap(temp2, temp1);
}
while (temp1 != temp2) {
temp2 += 1;
ans++;
}
return ans;
}
(1).我们创建两个Data类,一个存储 *this ,另一个存储d,并且判断那个那个小,把小的交换到temp2,然后循环判断temp1是否不等于temp2,若不等于就ans++,并且将temp2+=1,直到temp1和temp2相等。最后返回ans,即是两日期相差天数。
2.18重载<<号
ostream& operator<<(ostream& out, const Data& d)
{
out << d._year << '/' << d._month << '/' << d._day << endl;
return out;
}
(1).输出年月日,最后要返回out,因为如果要考虑到连续输出的情况,cout<<d1<<d2<<d3。
2.19重载>>号
istream& operator>>(istream& in, Data& d) {
while (1)
{
in >> d._year >> d._month >> d._day;
if (!d.CheckDate())
{
cout << "输入日期非法:";
d.Print();
cout << "请重新输入!!!" << endl;
}
else
{
break;
}
}
return in;
}
(1).输入年月日,然后判断是否合法,如果合法就退出循环,否则一直重新输入。
(2).最后也是要返回in,因为要考虑到连续输入的情况,cin>>d1>>d2>>d3。
2.10 data.cpp源码
#include"data.h"
bool Data::operator<(const Data& d) const
{
if (_year < d._year)
{
return true;
}
else if (_year == d._year)
{
if (_month < d._year)
{
return true;
}
else if (_month == d._month)
{
return _day < d._day;
}
}
return false;
}
bool Data::operator==(const Data& d) const
{
return _year == d._year && _month == d._month && _day == d._day;
}
bool Data::operator<=(const Data& d) const
{
return *this < d || *this == d;
}
bool Data::operator>(const Data& d) const
{
return !(*this <= d);
}
bool Data::operator>=(const Data& d) const {
return *this > d || *this == d;
}
bool Data::operator!=(const Data& d) const
{
return !(*this == d);
}
Data Data::operator+(int day) const {
Data temp = *this;
temp += day;
return temp;
}
Data& Data::operator+=(int day) {
if (day < 0) {
return *this -= (-day);
}
_day += day;
while (_day > Data::getday(_year, _month))
{
_day -= getday(_year, _month);
_month++;
if (_month > 12) {
_month = 1;
_year++;
}
}
return *this;
}
Data Data:: operator-(int day) const
{
Data temp = *this;
temp -= day;
return temp;
}
Data& Data::operator-=(int day) {
if (day < 0) {
return *this += (-day);
}
_day -= day;
while (_day <= 0) {
_month--;
if (_month == 0) {
_month = 12;
_year--;
}
_day += getday(_year, _month);
}
return *this;
}
Data Data::operator++(int)
{
Data temp = *this;
temp += 1;
return temp;
}
Data& Data::operator++()
{
*this += 1;
return *this;
}
Data Data:: operator--(int)
{
Data temp = *this;
temp -= 1;
return temp;
}
Data& Data::operator--()
{
*this -= 1;
return *this;
}
int Data::operator-(const Data& d) const {
int ans = 0;
Data temp1 = *this;
Data temp2 = d;
if (temp2 > temp1) {
swap(temp2, temp1);
}
while (temp1 != temp2) {
temp2 += 1;
ans++;
}
return ans;
}
ostream& operator<<(ostream& out, const Data& d)
{
out << d._year << '/' << d._month << '/' << d._day << endl;
return out;
}
istream& operator>>(istream& in, Data& d) {
while (1)
{
in >> d._year >> d._month >> d._day;
if (!d.CheckDate())
{
cout << "输入日期非法:";
d.Print();
cout << "请重新输入!!!" << endl;
}
else
{
break;
}
}
return in;
}
bool Data::CheckDate()const
{
if (_month <= 0 || _month > 12 || _day<1 || _day>getday(_year, _month)) {
return false;
}
return true;
}
void Data::Print()const {
cout << _year << '/' << _month << '/' << _day << endl;
}
Data::Data(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
if (!CheckDate())
{
cout << "非法日期:";
Print();
}
}
本篇完