Classes and Objects - Implementation of the Date Class

content

constructor initialization

print function

Size comparison of date classes

> operator overloading

Overloading of the == operator

Overloading of the >= operator

< operator overloading

Overloading of the <= operator

Overloading of the != operator

date operations

date += number of days

date + days

date -= number of days

date-day

prefix++

post ++

Pre--

rear--

date - date

print day of the week


 

  After learning 6 default member functions , we can complete the date class . We usually need to calculate what number will be after 100 days? What day is it? How many days have passed since XXX? And so on. We need to rely on custom types to implement these member functions.

First give the declaration of our member functions and member variables

#pragma once
#include<iostream>
#include<stdbool.h>
using namespace std;
class Date
{   
public:
	Date(int year = 1, int month = 1, int day = 1);//声明
	void Print()const;//打印
	int GetMonthDay(int year, int month)const;//获取这年某月的天数

	bool operator>(const Date& d)const;//>运算符重载
	bool operator<(const Date& d)const;//<运算符重载
	bool operator==(const Date& d)const;//==运算符重载
	bool operator!=(const Date& d)const;//不等于运算符重载
	bool operator>=(const Date& d)const;//>=运算符重载
	bool operator<=(const Date& d)const;//<=运算符重载

	Date& operator+=(int day);//加等于
	Date operator+(int day)const;//加
	Date& operator-=(int day);//减等于
	Date operator-(int day)const;//减

	Date& operator++();//前置++
	Date operator++(int);//后置++
	Date& operator--();//前置--
	Date operator--(int);//后置--

	int operator-(const Date& d)const;//日期-日期
	void PrintWeekDay()const;//判断星期几
private:
	int _year;
	int _month;
	int _day;
};

constructor initialization

The first problem we encountered is that, given a date, we need to judge the rationality and existence of the date.

Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
	//判断传入时间的合法性,例如2022-13-27
	if (!(_year > 0
		&& (_month > 0 && _month < 13)
		&& (_day > 0 && _day <= GetMonthDay(_year, _month))))
	{
		cout << "非法日期:" << endl;
		Print();
	}
}
int Date::GetMonthDay(int year, int month)const//获取这年某月的天数
{
	static int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int day = days[month];
	//闰年判断:四年一闰,百年不闰,四百又闰
	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
	{
		day += 1;
	}
	return day;
}

Write about the problem with GetMonthDay

The first problem is the leap year problem. We need to get the number of days in this year and this month, and inevitably we will encounter the problem of judging leap years.

①You can use 12 if else statements to judge our leap month

② can use switch case statement

③ The above code seems to be redundant. Since we all know the number of days in each month for 12 months, we can store these months in a static array , where the subscript is 0, initialized to 0, and the rest of the months can be write quickly

The second problem is that we can first determine whether it is February (month==2), because when it is not February, we do not need to determine whether it is a leap year

print function

We can directly use the standard output

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

Size comparison of date classes

It should be noted that the member function of the class, the default first parameter is the hidden this pointer, and the second parameter is the right operand

> operator overloading

The idea is relatively straightforward, the year is bigger, the year is bigger than the month, the month is bigger, the month is bigger than the sky, and the sky is bigger than the sky

bool Date::operator>(const Date& d)const//大于
{
	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;
}

Overloading of the == operator

Equal means that if two dates are equal, then they are both equal

bool Date:: operator==(const Date& d)const//等于
{
	return _year == d._year
		&& _month == d._month
		&& _day == d._day;
}

Overloading of the >= operator

Date needs to be greater than or equal to

bool Date:: operator>=(const Date& d)const//大于等于
{
	return *this > d || *this == d;
}

< operator overloading

Less than we can easily think of is the opposite of less than or equal to

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

Overloading of the <= operator

The opposite of less than or equal to is greater than, we can easily think of

bool Date::operator<=(const Date& d)const//小于等于
{
	return !(*this > d);
}

Overloading of the != operator

bool Date::operator!=(const Date& d)const //不等于
{
	return !(*this == d);
}

date operations

date += number of days

The first thing that comes to our mind is definitely the issue of carry. First, add the number of days to the day, and consider whether the date is legal. If it is illegal, consider the rounding issue.

Carry problem:

1. Round up to the month when the sky is full (if the sky is full, subtract the number of days in the current month, and add 1 to the month)

2. Carry over the previous year when the moon is full (if the moon is full, add 1 to the year and reset the month to 1)

returns *this:

+= is the two operand symbols, we also need to return the left operand, *this is actually the date after the d object is updated

Reference returns:

In order to reduce value copying, *this is actually an alias for d, we can just return it directly

In the special case , if the addition is a negative number of days, we have -= the negative of the current number of days

Date& Date::operator+=(int day)//加等于
{
	if (day < 0)//当day为负数时,处理一下
	{
		return *this -= -day;
	}

	_day += day;

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

	return *this;
}

date + days

The difference between + and += is the return value.

For example: d1+10 will not change the value of d1, while d1+=10 will change the value of d1

Date Date::operator+(int day)const//加
{
	Date ret(*this);//运用拷贝构造
	ret += day;//复用已经实现的 +=
	//实际上的编译器会这样处理 
	//ret.operator+=(day);
	return ret;
}

date -= number of days

The first thing that comes to our mind is the borrowing problem. We first subtract the number of days from the day to determine whether the date is legal. If it is not legal, we must consider the borrowing problem.

Resignation question:

1. Subtract out if the day is a negative number, the month is -1

2. If the month is reduced to 0 (month==0), we have to borrow from previous years, the year is -1, and the month is reset to 12

3. The last day plus the number of days in the month

In the special case , if subtracting a negative number of days, we have += the negative of the current number of days

Date& Date::operator-=(int day)//减等于
{
	if (day < 0)//当day为负数时,处理一下
	{
		return *this += -day;
	}

	_day -= day;

	while (_day <= 0)
	{
		_month--;
		if (_month == 0)
		{
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

date-day

The difference between - and -= is also the difference in return value

The return value we want to get here is the value after the change

Date Date::operator-(int day)const//减
{
	Date ret(*this);
	ret -= day;
	return ret;
}

Pre-++ and post-++, the biggest difference between the two is the difference in the return value. Pre-++ returns the value after the addition, and post-++ returns the value before the addition.

In order to distinguish the pre- and post-operators in C++, we introduce a parameter placeholder in post-++ to distinguish the overloading of these two functions, which has no practical significance.

Note: The post ++ needs to return the value before the addition. We first use *this to copy and construct a ret object (actually save a copy of the value before the addition). Since the ret object is out of scope, it will be It is destroyed, so it cannot be returned by reference, but can only be returned by passing a parameter, which is equivalent to copying a copy to Date again. The pre-addition can directly return the reference, reducing copying.

prefix++

Date& Date::operator++()//前置++,返回加加后的值
{
	*this += 1;
	return *this;
}

post ++

Date Date::operator++(int)//后置++,返回加加前的值
{
	Date ret(*this);//拷贝构造
	*this += 1;
	return ret;
}

Pre--

Date& Date::operator--()//前置--
{
	Date ret(*this);//拷贝构造
	*this -= 1;
	return *this;
}

rear--

Date Date::operator--(int)//后置--
{
	Date ret(*this);//拷贝构造
	*this -= 1;
	return ret;
}

date - date

We may need to calculate in our daily life, how many days are there between two dates, here we can calculate.

Idea: We can select a smaller date (add 1 to it), use it to "catch up" with the larger date, and then define a count variable, which will add itself as the smaller date is added, and catch up with it. Then the difference between the two days

int Date::operator-(const Date& d)const//日期-日期
{
	//我们不知道哪个日期大一点,所以假设
	Date max = *this;//先假设d1>d2
	Date min = d;
	int flag = 1;
	if (*this < d)//如果d1<d2,再交换最大值和最小值
	{
		max = d;
		min = *this;
		flag = -1;
	}
	int count = 0;
	while (min != max)
	{
		++min;
		++count;
	}
	return count * flag;
}

print day of the week

We sometimes need to find the day of the week for this date in our life, and now we can do it.

Idea: After searching, we found that January 1, 1900 happened to be Monday, we can use it as the starting point of time, store each week in an array, and calculate the difference between a certain date and 1900-1-1 The difference, the number of days finally obtained is modulo 7 to know the day of the week.

void Date::PrintWeekDay()const
{
	const char* arr[] = { "星期一","星期二","星期三","星期四","星期五","星期六","星期日" };
	/*Date start(1900, 1, 1);
	int count = *this - start;*/
	//匿名对象
	int count = *this - Date(1900, 1, 1);
	cout << arr[count % 7] << endl;
}

Thanks for watching! 

Guess you like

Origin blog.csdn.net/weixin_57675461/article/details/123020393