文章目录
#include<iostream>
using namespace std;
class Date
{
public:
//获取一个月中的天数
int GetMonthDay(int year,int month);
//构造函数,不要在你的声明和定义中同时写入缺省值
Date(int year, int month, int day);
//拷贝构造函数
Date(const Date& d);
//==
bool operator==(const Date& d);
//这里的bool值代表的返回的是真假的情况
//>
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& Date::operator=(const Date& d);
//+= 日期加日期是没有意义的,但是日期加天数就是有意义的
Date& operator+=(int day);
//+
Date operator+(int day);
//-=
Date& Date::operator-=(int day);
//-
Date Date::operator-(int day);
//++(前置)
Date& Date::operator++();
//++(后置)
Date Date::operator++(int);
//--(前置)
Date& Date::operator--();
//--(后置)
Date Date::operator--(int);
//日期-日期也是有意义的
int operator-(const Date& d);
void Print();
private:
int _year;
int _month;
int _day;
};
Date.cpp
#include"Date.h"
int Date::GetMonthDay(int year, int month)
{
//除了2月(和是否是闰年有关),其他的月份的基本天数是不会发生改变的
static int daysArr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //因为这个函数会被频繁的调用,如果每次调用都重新开空间写入太过麻烦,所以直接把它扔到静态区
int days = daysArr[month];
//所以这里只剩下2月需要判别
if (month = 2 &&
(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))//闰年
{
days = 29;
}
return days;
}
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
if (!(year >= 0 &&
month > 0 && month < 13 &&
day > 0 && day <= GetMonthDay(year, month)))
{
cout << "日期非法" << endl;
}
}
void Date::Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
// = 既然这里是赋值运算符,那么应该有返回值,返回值应该是d2,因为this是d2地址的指针,即使出了作用域,d2依旧存在,所以可以使用引用传参,可以减少两次拷贝
Date& Date::operator=(const Date& d)
{
//就是要把d3的值给d2 ,这个判断就是避免自己给自己赋值,这个是没有任何意义的
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this; //虽然这个this不常加,但是这里是需要使用到的
}
//d1 + =100,返回值:d1
//先把天加到日期天上。如果日期不合法,就剪掉当月的天数,然后进一个月。再继续看不合法,在继续减掉当月的天数再进月,如果月满,往年进位
Date& Date::operator += (int day)
{
if (day < 0)
{
return *this -= -day;//你这个day本身就是-的,所以一个负负就得正了
}
_day += day;
// 日期是否合法
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
_month++;
if (_month == 13)
{
_year++;
_month = 1;
}
}
return *this;//最后返回的应该是一个日期
}
//- 这里和上面一样不能够修改本来的d1值,所以需要拷贝构造函数
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);
ret -= day;
return ret;
}
// +
Date Date::operator+(int day)//第一个Date是返回值,第一个Date是指类;出了作用域ret不存在,所以使用传值Date返回,不使用引用
{
// 方法1:跟+=实现,逻辑类似冗余
/*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;*/
//方法2:
Date ret(*this);
ret += day; // 相当于ret.operator+=(day);
return ret;
}
//-=
Date& Date::operator-=(int day)
{
_day -= day;
while (_day < 0)
{
_month--;
if (_month == 0)
{
_year--;
_month = 12;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
// ++d1 等价于 d1 += 1
// 转换为d1.operator++(&d1);
// 返回++之后的值
Date& Date::operator++()
{
*this += 1;
return *this;
}
// d1++
// 转化为:d1.operator++(&d1, 0);
// 返回++之前的值
Date Date::operator++(int)
{ Date ret(*this);
*this += 1;
return ret;
}
//传引用的时候,尽量加const ,因为你并不希望修改d1里面本来的值,你只是希望d2和d1相同
// d1 == d2
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)
{
if (_month > d._month)
{
return true;
}
else if (_month == d._month)
{
if (_day > d._day)
{
return true;
}
}
}
return false;
}
// d1 != d2
bool Date::operator!=(const Date& d)
{
return !(*this == d);//代码复用bool Date::operator==(const Date& d)
}
// d1 >= d2
bool Date::operator>=(const Date& d)
{
return *this > d || *this == d;
}
// d1 < d2
bool Date::operator<(const Date& d)
{
return !(*this >= d);
}
// d1 <= d2
bool Date::operator<=(const Date& d)
{ return !(*this > d);//代码复用bool Date::operator>(const Date& d)
}
// d1(即this) - d2(即d)
int Date::operator-(const Date& d)
{
// 直接进行日期之间相减,不好操作
Date max = *this, min = d;
int flag = 1;
if (*this < d)
{
max = d;
min = *this;
flag = -1;
}
int n = 0;
while (min != max)
{
++n;
++min;//自定义类型min重载之后,用起来和内置类型感觉一样
}//小的往大的那个方向+,+满之后会自动往月、年上进位,+了多少次=相差多少天
return n*flag;
}
//构造函数
Date::Date(int year = 1900, int month= 1, int day=1)
{
if (year>0
&& month>0 && month<13
&& day>0 && day<GetMonthDay(year,month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "日期非法" << endl;
}
}
Date.h
#pragma once
#include <iostream>
using namespace std;
class Date
{
public:
int GetMonthDay(int year, int month);
void Print();
Date(int year = 1900, int month = 1, int day = 1);
// d1 += 10
Date& operator+=(int day);
// d1 + 10
Date operator+(int day);
// d1 -= 10
Date& operator-=(int day);
// d1 - 10
Date operator-(int day);
// ++d1
// d1.operator++(&d1);
Date& operator++();
// 加了一个用以区别的形参int,这个参数不使用,仅仅是为了跟前置++构成函数重载区分开来
// d1++
// d1.operator++(&d1, 0);
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);
// d1 - d2
int operator-(const Date& d);
private:
int _year;
int _month;
int _day;
};
Test.cpp
#include<iostream>
using namespace std;
#include "Date.h"
int main()
{ Date d1(2021, 2, 3);
d1.Print();
Date ret = d1 + 100;//d1没被 改变
ret.Print();
d1 += 100;//d1被 改变
d1.Print();
ret = d1 + -100;
ret.Print();
d1++;
++d1;
//Date d2(2020, 2, 29);
//d2.Print();
//Date d3(2021, 13, 0);
//d3.Print();
Date d3(2021, 2, 3);
Date d4(2021, 8, 1);
cout << d3 - d4 << endl;
cout << d4 - d3 << endl;
return 0;}
d1 += 100;的计算过程: