一、date.h文件(声明)
#pragma once
#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);
// 全缺省的构造函数
Date(int year = 1900, int month = 1, int day = 1); //全缺省函数,声明时给缺省值,定义函数不要给
// 拷贝构造函数
// d2(d1)
Date(const Date& d);
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& operator=(const Date& d);
// 析构函数
~Date();
// 日期+=天数
Date& operator+=(int day);
// 日期+天数
Date operator+(int day);
// 日期-天数
Date operator-(int day);
// 日期-=天数
Date& operator-=(int day);
// 前置++
Date& operator++();
// 为了区分,构成重载,给后置++,强⾏增加了⼀个int形参
// 这⾥不需要写形参名,因为接收值是多少不重要,也不需要⽤
// 这个参数仅仅是为了跟前置++构成重载区分
// 后置++
Date operator++(int);
// 后置--
Date operator--(int);
// 前置--
Date& operator--();
// >运算符重载
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);
void Print();
private:
int _year;
int _month;
int _day;
};
二、add.cpp文件(定义)
#include"date.h"
// 获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{
static int arr[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };//静态数组
//如果是闰年的2月份,2月份多一天
if ((month == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
return 29;
return arr[month];//返回某年某月的天数
}
// 全缺省的构造函数
Date::Date(int year , int month , int day )//全缺省函数,声明时给缺省值,定义函数时不要给
{
_year = year;
_month = month;
_day = day;
}
// 拷贝构造函数
// d2(d1)
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& Date:: operator=(const Date& d)
{
if (*this != d)//防止给本身赋值
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this; //d1=d2的返回值是d1,也就是*this
}
// 析构函数
Date::~Date()
{
_year = 0;
_month = 0;
_day = 0;
}
// 日期+=天数
Date& Date:: operator+=(int day)//日期自己本身需要改变
{
_day += day;
int n= GetMonthDay(_year, _month);//得到该月的天数
while (_day > n) //如果加到的总天数大于该月的总天数,就要跳到下一个月
{
if (_month == 12)//如果是12月,加一个月,就到了下一年的一月
{
_year += 1;
_month = 1;
}
else
_month += 1;//月数加1
_day -= n;
n = GetMonthDay(_year, _month);//更新到下一个月的天数
}
return *this;
}
// 日期+天数
Date Date::operator+(int day)//日期自己本身不需要改变
{
//方法1:附用+=运算符(方便)
Date temp(*this);拷贝构造一个临时变量,改变这个临时变量的值
temp += day;// 附用-=运算符重载
return temp;
//方法2:不附用+=运算附(不方便)
//Date temp(*this);//拷贝构造一个临时变量,改变这个临时变量的值
//temp._day += day;
//int n = GetMonthDay(temp._year, temp._month);//得到该月的天数
//while (temp._day > n) //如果加到的总天数大于该月的总天数,就要跳到下一个月
//{
// if (temp._month == 12)//如果是12月,加一个月,就到了下一年的一月
// {
// temp._year += 1;
// temp._month = 1;
// }
// else
// temp._month += 1;//月数加1
// temp._day -= n;
// n = GetMonthDay(temp._year, temp._month);//更新到下一个月的天数
//}
//return temp;
}
// 日期-天数
Date Date::operator-(int day)//日期自己本身不需要改变
{
Date temp(*this);拷贝构造一个临时变量,改变这个临时变量的值
temp -= day;// 附用-=运算符重载
return temp;
}
日期-=天数
Date& Date::operator-=(int day)//日期自己本身需要改变
{
_day -= day;
int n ;//得到该月的天数
while (_day<=0) //如果减到的值大于0,就不需改变年和月,小于0就要改变月(可能改变年)
{
if (_month == 1)//如果是1月,减一个月,就到了前一年的12月
{
_year -= 1;
_month = 12;
}
else
_month -= 1;//月数减1
n = GetMonthDay(_year, _month);//更新到前一个月的天数
_day = _day + n;
}
return *this;
}
// 前置++
Date& Date::operator++()//返回++后的值
{
*this += 1;//附用+=运算符重载
return *this;
}
// 后置++
Date Date::operator++(int)//返回++前的值
{
Date temp(*this);//拷贝构造一个临时变量
*this += 1;//附用+=运算符重载
return temp;
}
// 后置--
Date Date::operator--(int)//返回--前的值
{
Date temp(*this);//拷贝构造一个临时变量
*this -= 1;//附用-=运算符重载
return temp;
}
// 前置--
Date& Date::operator--()//返回--后的值
{
*this -= 1;//附用-=运算符重载
return *this;
}
// 日期-日期 返回天数
int Date:: operator-(const Date& d)//从小的日期开始,每次都加1天,总计一共加了多少天,就是日期的差值
{
Date max = *this;//假设法
Date min = d;
int flag = 1;
if (*this < d) //相差负数天(被减数小于减数)
{
max = d;
min = *this;
flag = -1;
}
int i = 0;
while (min < max)
{
min++;
i ++ ;
}
return i*flag;
}
// ==运算符重载
bool Date::operator==(const Date& d)
{
if (_year == d._year && _month == d._month && _day == d._day)
return true;
else
return false;
}
// >运算符重载
bool Date::operator>(const Date& d)
{
if ( (_year > d._year)||( (_year==d._year)&&(_month>d._month) )||
((_year == d._year) && (_month == d._month)&&(_day>d._day)) )
return true;
else
return false;
}
// >=运算符重载
bool Date::operator >= (const Date& d)
{
if (!operator<(d))//如果不小于,则是大于等于
return true;
else
return false;
}
// <运算符重载
bool Date::operator < (const Date& d)
{
if ((_year < d._year) || ((_year == d._year) && (_month < d._month)) ||
((_year == d._year) && (_month == d._month) && (_day < d._day)))
return true;
else
return false;
}
// <=运算符重载
bool Date::operator <= (const Date& d)
{
if (!operator>(d))//如果不大于,则是小于等于
return true;
else
return false;
}
// !=运算符重载
bool Date::operator != (const Date& d)
{
if(operator==(d))//附用判断相等的函数。如果相等,说明不相等
//if (*this == d)
return false;
else
return true;
}
void Date::Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
ostream& operator<<( ostream& out,const Date&d )//输出函数
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out; //返回值是ostream类型的引用,使得它可以连续输出
}
istream& operator>>(istream& in, Date& d)//输入函数
{
cout << "请依次输入年月日" << endl;
in>>d._year >> d._month >> d._day;
return in; //返回值是istream类型的引用,使得它可以连续输入
}
三、test.cpp文件(测试)
#include"date.h"
int main()
{
Date d1(2024, 11, 1);
Date d2(1778, 11, 1);
Date d4(1, 1, 1);
cout << d1 << d2 << d4 << endl;
Date d5;
cout << d5 << endl;
cin >> d5;
cout << d5 << endl;
//d1.Print();
//d2.Print();
//d3.Print();
//d4.Print();
//printf("\n");
//d1 = d2 = d3 = d4;
//d1.Print();
//d2.Print();
//d3.Print();
//d4.Print();
/*int n = d2 - d1;
printf("%d", n);*/
//d1.Print();
//Date d2 = d1--;
//d2.Print();
//d1.Print();
//d1 -= 10;
//Date d1(2024, 9,30);
//d1.Print();
//Date d2=++d1;
//d2.Print();
d1 -= 10;
//d1.Print();
/*Date d5 = d1 +100000;
d1.Print();
d5.Print();*/
/*Date d2(2024, 10, 1);
d2.Print();
d2 -= 100000;
d2.Print();*/
//Date d3 = d2;//赋值拷贝(因为这里d3这个类,正在被创建,所以是赋值拷贝
//d3.Print();
//Date d4(d2);//赋值拷贝
//d4.Print();
//d4 = d1;//这里是赋值运算符重载,因为d4和d1都是已经存在的类
//d4.Print();
return 0;
}