目录
在前面几节的内容中,我们学习了类的基本知识,其中比较重要的是类的6个默认成员函数,在这节中我们主要对前几节的内容进行实际应用,实现一个简单的日期类
一.日期类
1.类的构造函数和拷贝构造
对于一个日期类,我们首先能够想到的便是初始化一个日期和日期的复制
Date::Date(int year = 0, int month = 1, int day = 1) :_year(year), _month(month), _day(day)
{
_year = year;
_month = month;
_day = day;
}
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
我们很容易可以写出上面的构造函数,但是有一个问题是我们可以输入各种日期,即便是2024年55月56日这种不合法的日期,所以我们需要对其进行范围的限定,对于年和月的范围我们可以通过year>=0,month>=1&&month<=12进行控制,但是日却不好控制,因为1个月中有30,31,28,29这种情况,所以我们可以写一个函数来获取每月的日数
int Date::GetMonthDay(int year, int month)
{
static int monthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
//4年一闰,100年不闰,400年一闰
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
{
return 29;
}
return monthDays[month];
}
构造函数可以修改为
Date::Date(int year = 0, int month = 1, int day = 1) :_year(year), _month(month), _day(day)
{
if (year >= 0 && month >= 1 && month <= 12 && day >= 1 && day <= GetMonthDay(year, month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "日期错误" << endl;
}
}
2.日期的比较
我们可以比较两个日期的大小,是否相等其他操作,比如<,>,==,<=,>=,!=
bool Date::operator==(const Date& d)
{
return _year == d._year && _month == d._month && _day == d._day;
}
bool Date::operator<(const Date& d)
{
if (_year < d._year)
return true;
else if (_year == d._year && _month < d._month)
return true;
else if(_year == d._year && _month == d._month && _day < d._day)
return true;
return false;
}
当我们实现<和==时,对于<=便很好实现,对上面的函数进行复用即可
bool Date::operator<=(const Date& d)
{
return *this < d || *this == d;
}
对于>,我们可以选择对年,月,日依次比较,也可以选择取反<=
bool Date::operator>(const Date& d)
{
/*if (_year > d._year)
return true;
else if (_year == d._year && _month > d._month)
return true;
else if (_year == d._year && _month == d._month && _day > d._day)
return true;
return false;*/
return !(*this <= d);
}
>=对<取反即可
bool Date::operator>=(const Date& d)
{
/*return *this > d || *this == d;*/
return !(*this < d);
}
!=对==取反
bool Date::operator!=(const Date& d)
{
return !(*this == d);
}
3.日期加减一个天数
1.日期加天数
对于加上一个天数,我们需要考虑的便是月和年的进位,所以我们只需要将天数加上,与当前月份天数比较,如果大于就将其减去,月份++,直到天数小于当前月份天数,如果月份加到13,就年++,将月份置为1
注意:如果我们不希望原来的天数发生改变,就需要用一个临时变量来记录,若不记录的话,如d2=d1+100,我们只希望改变d2,但是d1也会改变
Date Date::operator+(int day)
{
Date ret(*this);
ret._day += day;
while (ret._day > GetMonthDay(ret._year, ret._month))
{
ret._day -= GetMonthDay(ret._year, ret._month);
ret._month++;
if (ret._month == 13)
{
ret._year++;
ret._month = 1;
}
}
return ret;
}
实现了+,那么+=直接复用即可
Date Date::operator+=(int day)
{
Date ret(*this);
*this =*this+ day;
return *this;
}
2.日期减天数
对于减去一个天数,原理与加天数相似,只是天数<=0的时候,月份减1,当月份减到0,年份减1,月份置为12
Date Date::operator-(int day)
{
Date ret(*this);
ret._day -= day;
while (ret._day <= 0)
{
ret._month--;
if (ret._month == 0)
{
ret._year--;
ret._month = 12;
}
ret._day += GetMonthDay(ret._year, ret._month);
}
return ret;
}
对于-=复用-即可
Date Date::operator-=(int day)
{
Date ret(*this);
*this = *this - day;
return *this;
}
4.日期的++与--
1.日期的++
前置++
对与前置++,+=1即可
//前置++
Date Date::operator++()
{
*this += 1;
return *this;
}
后置++
因为后置++,需要用完在+,所以需要一个临时变量记录
//后置++;
Date Date::operator++(int)
{
Date ret(*this);
*this += 1;
return ret;
}
2.日期的--
前置--
//前置--
Date Date::operator--()
{
*this -= 1;
return *this;
}
后置--
//后置--
Date Date::operator--(int)
{
Date ret(*this);
*this -= 1;
return ret;
}
5.日期减日期
我们有时需要知道两个日期之间相差几天,所以写一个函数会更方便
创建两个日期对象max和min,分别指向当前对象(*this)和参数对象(d).使用flag来确定结果的符号,使用operator<来判断哪个日期更早.如果*this < d,则交换max和min的值,并将flag设为-1,表示结果是负的,使用一个循环,不断增加min,直到其大于或等于max,同时计数n,表示经过的天数,返回n * flag,得到两个日期之间的差值
//日期减日期
int Date::operator-(const Date& d)
{
Date max = *this;
Date min = d;
int flag = 1;
if (*this < d)
{
flag = -1;
max = d;
min = *this;
}
int n = 0;
while (min < max)
{
min++;
n++;
}
return n * flag;
}
6.日期的输入和输出
当我们在类中使用<<和>>显示没有合适的构造函数匹配,我们尝试重载,但是发现没有办法重载为成员函数,因为cout和this指针在抢第一个参数位置,所以我们重载为全局函数,却无法访问私有成员,这时候就需要用到友元
ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
istream& operator>>(istream& in, Date& d)
{
while (1)
{
in >> d._year >> d._month >> d._day;
if (d._year >= 0 && d._month >= 1 && d._month <= 12 && d._day >= 1 && d._day <= d.GetMonthDay(d._year, d._month))
break;
else
cout << "非法日期,请重新输入" << endl;
}
return in;
}
二.整体代码
1.Date.h
#pragma once
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year, int month, int day);
Date(const Date& d);
int GetMonthDay(int month, int year);
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);
Date operator+(int day);
Date operator-(int day);
Date operator+=(int day);
Date operator-=(int day);
int operator-(const Date & d);
Date operator++();
Date operator++(int);
Date operator--();
Date operator--(int);
friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& in, Date& d);
private:
int _year;
int _month;
int _day;
};
2.Date.cpp
#include "Date.h"
int Date::GetMonthDay(int year, int month)
{
static int monthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
//4年一闰,100年不闰,400年一闰
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
{
return 29;
}
return monthDays[month];
}
Date::Date(int year = 0, int month = 1, int day = 1) :_year(year), _month(month), _day(day)
{
if (year >= 0 && month >= 1 && month <= 12 && day >= 1 && day <= GetMonthDay(year, month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "日期错误" << endl;
}
}
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
bool Date::operator==(const Date& d)
{
return _year == d._year && _month == d._month && _day == d._day;
}
bool Date::operator<(const Date& d)
{
if (_year < d._year)
return true;
else if (_year == d._year && _month < d._month)
return true;
else if(_year == d._year && _month == d._month && _day < d._day)
return true;
return false;
}
bool Date::operator<=(const Date& d)
{
return *this < d || *this == d;
}
bool Date::operator>(const Date& d)
{
/*if (_year > d._year)
return true;
else if (_year == d._year && _month > d._month)
return true;
else if (_year == d._year && _month == d._month && _day > d._day)
return true;
return false;*/
return !(*this <= d);
}
bool Date::operator>=(const Date& d)
{
/*return *this > d || *this == d;*/
return !(*this < d);
}
bool Date::operator!=(const Date& d)
{
return !(*this == d);
}
Date Date::operator+(int day)
{
Date ret(*this);
ret._day += day;
while (ret._day > GetMonthDay(ret._year, ret._month))
{
ret._day -= GetMonthDay(ret._year, ret._month);
ret._month++;
if (ret._month == 13)
{
ret._year++;
ret._month = 1;
}
}
return ret;
}
Date Date::operator+=(int day)
{
Date ret(*this);
*this =*this+ day;
return *this;
}
Date Date::operator-(int day)
{
Date ret(*this);
ret._day -= day;
while (ret._day <= 0)
{
ret._month--;
if (ret._month == 0)
{
ret._year--;
ret._month = 12;
}
ret._day += GetMonthDay(ret._year, ret._month);
}
return ret;
}
Date Date::operator-=(int day)
{
Date ret(*this);
*this = *this - day;
return *this;
}
//前置++
Date Date::operator++()
{
*this += 1;
return *this;
}
//后置++;
Date Date::operator++(int)
{
Date ret(*this);
*this += 1;
return ret;
}
//前置--
Date Date::operator--()
{
*this -= 1;
return *this;
}
//后置--
Date Date::operator--(int)
{
Date ret(*this);
*this -= 1;
return ret;
}
//日期减日期
int Date::operator-(const Date& d)
{
Date max = *this;
Date min = d;
int flag = 1;
if (*this < d)
{
flag = -1;
max = d;
min = *this;
}
int n = 0;
while (min < max)
{
min++;
n++;
}
return n * flag;
}
ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
istream& operator>>(istream& in, Date& d)
{
while (1)
{
in >> d._year >> d._month >> d._day;
if (d._year >= 0 && d._month >= 1 && d._month <= 12 && d._day >= 1 && d._day <= d.GetMonthDay(d._year, d._month))
break;
else
cout << "非法日期,请重新输入" << endl;
}
return in;
}
int main()
{
Date d1;
Date d2(1999, 2, 3);
Date d3(d1);
cout << d1 << d2 << d3;
cout << (d3 == d1) << endl;
cout << (d1 < d2) << endl;
cout << (d1 <= d2) << endl;
cout << (d1 > d2) << endl;
cout << (d1 >= d2) << endl;
cout << (d1 != d2) << endl;
d2 += 100;
cout << d2;
d2 -= 100;
cout << d2;
Date d(2024, 1, 1);
d3 = ++d;
cout << d3;
cout << d;
d3 = d++;
cout << d3;
cout << d;
d3 = --d;
cout << d3;
cout << d;
d3 = d--;
cout << d3;
cout << d;
Date d4 = d2 + 100;
cout << d4;
Date d5 = d2 - 100;
cout << d5;
Date d6(2024, 3, 1);
Date d7(2024, 4, 1);
cout << d7 - d6 << endl;
Date d8;
cin >> d8;
cout << d8;
}
标签:实现,year,C++,month,int,日期,._,Date,day
From: https://blog.csdn.net/w200514/article/details/143337668