【关于日期类的详细实现和分析】

文章目录

  • 关于日期类对象的操作:
    • 1.日期类的构建
    • 2.获取每个月天数的函数
    • 3.构造函数
    • 4.判断两个日期的大小关系
    • 5.日期加减天数的实现
    • 6.日期减日期的实现
    • 7.日期的自增和自减

关于日期类对象的操作:

在生活当中,关于日期我们肯定不陌生,比如各种节日都要用一个日期来定义是在哪一天;而对于日期来说我们不妨把它归为一类,在现实生活中日期是一个实体,我们把日期构建为日期类,下面我们就来实现关于日期类经常用的相关操作。

1.日期类的构建

我们知道描述一个日期是以哪一年、哪一月、哪一天来描述的,所以在我们自定义类型构建日期类的时候,日期类的成员就是年、月和日,日期类的成员函数就是来实现关于日期类的各种操作的,构建如下:

#include 
using namespace std;

//日期类
class Date
{
public:
	void Print();
	int GetMonthDay(int year, int month);
	Date(int year=0,int month=0,int day=0); //构造函数
	Date(const Date& d);   //拷贝构造函数

	//运算符重载,判断两个日期类的大小关系
	bool operator>(Date& d);
	bool operator==(Date& d);
	bool operator>=(Date& d) ;
	bool operator<(Date& d);
	bool operator<=(Date& d);
	bool operator!=(Date& d);
    
    //实现日期类加减一个天数的结果
	Date& operator+=(int n);
	Date operator+(int n) const;
	Date& operator-=(int n);
	Date operator-(int n);

    //实现两个日期相差的天数
	int operator-(const Date& d);
    
    //实现日期的自增和自减
	Date& operator++();
	Date operator++(int);
	Date& operator--();
	Date operator--(int);

private:
	int _year;
	int _month;
	int _day;
};

2.获取每个月天数的函数

对于日期来说,获取每个月的天数是有很大意义的,因为不同的年份和月份造成的结果有特殊性,比如每一年的二月份,要判断是否为润年还是平年,如果是平年就28天,润年就是29天。还有为了实现其它日期的操作也是需要这个函数的,获取每个月天数的函数如下:

//在日期类当中的获取每个月天数的函数
int Date::GetMonthDay(int year, int month)
{
	static int sum[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int day = sum[month];

	//判断是否为润年并且为2月份
	if ((month == 2) &&
	((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
	{
		day++;
	}
	return day;
}

3.构造函数

我们知道当我们创建一个日期类的过程中,编译器会帮我们调用构造函数,如果我们不实现构造函数,那么编译器会帮我们自动生成一个,但是自动生成的默认构造函数是不对内置类型进行处理的,从而也初始化不了对象;所以我们必须要自己写一个构造函数,并且这个构造函数还要判断日期是否合理,比如2022.15.52 这个日期就是不合理的。构造函数如下:

//打印日期函数
void Date::Print()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

Date::Date(int year, int month, int day)
{
	//先进行初始化
	_year = year;
	_month = month;
	_day = day;
	//再判断日期是否合理
	if((year<1) || (month>12&&month<1) 
		|| (day > GetMonthDay(year, month)))
	{
		cout << "日期不合法:" ;
		Print();
	}
}

4.判断两个日期的大小关系

在以前的C语言语法中我们只能对内置类型进行运算符操作,不能对自定义类型(如结构体)进行运算符操作;C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数;所以我们就可以对自定义类型进行运算符操作,从而可以实现两个日期的大小关系,实现函数如下:

//判断日期d1是否打印日期d2
bool Date::operator>(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;
	}
	else
	{
		return false;
	}
}

//判断两个日期是否相同
bool Date::operator==(Date& d)
{
	if (_year == d._year && _month == d._month && _day == d._day)
	{
		return true;
	}
	return false;
	
}

//对前面实现的运算符>和==进行复用
bool Date::operator>=(Date& d) 
{
	return (*this > d) || (*this == d);
}

bool Date::operator<(Date& d)
{
	return !(*this >= d);
}

bool Date::operator<=(Date& d)
{
	return (*this < d) || (*this == d);
}

bool Date::operator!=(Date& d)
{
	return !(*this == d);
}

5.日期加减天数的实现

关于日期类的对象我们还有很多要实现的,比如在日常生活中我们想知道一个日期加减某一天是多少,而在日期类中我们要可以实现出来,下面对+= 、+和-、-=运算符的实现,要注意的是+=才能对本身进行改变,而+并不能对本身改变;函数如下:

//日期加上天数后是多少
Date& Date::operator+=(int n)
{
	//如果天数为负值就对-=运算符复用
	if (n < 0)
	{
		return *this -= n;
	}

	_day += n;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13)
		{
			_month = 1;
			_year++;
		}
	}
	return *this;
}

Date Date::operator+(int n) const
{
	Date ret = *this;
	ret += n;
	return ret;
}

Date& Date::operator-=(int n)
{
	if (n < 0)
	{
		return *this += -n;
	}
	_day -= n;
	while (_day <= 0)
	{
		_month--;
		if (_month == 0)
		{
			_month = 12;
			_year--;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

Date Date::operator-(int n)
{
	Date ret = *this;
	ret -= n;
	return ret;
}

6.日期减日期的实现

在日常生活中日期加上日期是没有意义的,但日期减去一个日期就是两个日期之间的天数了,是有很大意义的,我们也可以在类中来实现,函数如下:

//日期-日期,参数是Date类型,和上面的日期减天数函数构成重载
int Date::operator-(const Date& d)
{
	int count = 0;
	int flag = 1;
	Date Max = *this;
	Date Min(d);
	if (Min>Max)
	{
		Max = d;
		Min = *this;
		flag = -1;
	}
	while (Min != Max)
	{
		Min += 1;
		count++;
	}
	return count * flag;
}

7.日期的自增和自减

在运算符中自增和自减是经常用到的,我们也可以来实现自定义类型日期类的自增和自减,但是要分为前置++还是后置++;前置++改变了先自增然后才使用,改变了自己本身;而后置++是先使用然后再自增;我们要注意其中的差别才行。

//前置++,对+=运算符进行复用
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;
}

你可能感兴趣的:(C++,C++,语法)