C++:日期类

学习目标:

加深对四个默认构造函数的理解:

1.构造函数

2.析构函数

3.拷贝构造

4.运算符重载

实现功能

1.比较日期的大小

2.日期+-天数

3.前/后置++,--

这里基本会使用运算符重载

定义一个日期类

class Date
{
public:
	//1.全缺省参数的构造函数
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_day = day;
		_month = month;
	}
 
	//2.构造拷贝函数
	Date(const Date& x)
	{
		_year = x._year;
		_month = x._month;
		_day = x._day;
	}
 
	//3.析构函数(这里可不构造)
	~Date() {}
 
	//4.运算符重载
	bool operator==(const Date& x);
 
private:
	int _year;
	int _month;
	int _day;
};

1.比较日期的大小

比较日期大小,只用写大于,等于或者小于,等于,其它功能去复用就行(关系互斥)

--功能声明:

C++:日期类_第1张图片

--等于实现:

//等于(d1 == d2;)
bool Date::operator==(const Date& x) 
{
	return this->_year == x._year
		&& this->_month == x._month
		&& this->_day == x._day;
}

--大于实现:

//大于(d1>d2)
bool Date::operator>(const Date& x) 
{
	if     ((_year > x._year)
		|| ((_year == x._year) && (_month > x._month))
		|| ((_year == x._year) && (_month == x._month) && (_day > x._day)))
		return true;
	else
		return false;
}

--小于等于

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

--大于等于

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

--小于:

//小于(d1= x);
}

--不等于:

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

效果:

C++:日期类_第2张图片

2.日期+-天数

准备工作:日期+-天数,要考虑到进位,借位,以及闰年,非闰年的月份天数问题:

给出函数:

--是否为闰年:

	//是否为闰年
	int is_leapyear(int year)
	{
		if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
		{
			return 1;
		}
		return 0;
	}

--获取月分的天数:
 

	//获取每一个月份的天数
	int GetMonthDay(int year, int month)
	{
		int month_day[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//存放每个月的月份
		int is_leap = is_leapyear(year);
		if (is_leap && month == 2)
		{
			return month_day[month] + 1;//是闰年,2月有29天
		}
		else
		{
			return month_day[month];//不是闰年且不是2月
		}
	}

功能声明:

C++:日期类_第3张图片

这里同样可以实现复用:

写好+=后可以复用+,写好-=可以复用-

为什么不是+复用+=呢?

--+天数不改变原来日期,+=会改变,直接用+=复用的时候,拷贝一份,传+=后的即可

实现:

日期+=天数

//日期+=天数(d1 += 100)
Date Date::operator+=(int day) 
{	
	if (day < 0) 
	{
		return *this -= -day;
	}
	//1.直接将天数加到该日期的月数中去
	_day += day;
	//2.判断是否超出当前月数的天数
	while (_day > GetMonthDay(_year,_month)) 
	{
		//3.超出就进位,重复
		_day -= GetMonthDay(_year,_month);
		_month++;
		//处理年份
		if (_month == 13) 
		{
			_month = 1;
			_year++;
		}
	}
	return *this;
}

日期+天数

//日期+天数(d1+100)
Date Date::operator+(int day) 
{
	//+,不改变date,拷贝一份
	Date ret(*this);
	ret += day;
	return ret;
}

日期-=天数:

//日期 -= 天数(	d1 - 100)
Date Date::operator-=(int day)
{
	if (day < 0) 
	{
		return *this += -day;
	}

	//1.天减去天
	_day -= day;
	//2.判断是否违法,违法向前面借
	while (_day <= 0)
	{
		_month--;
		//借月数
		if(_month <= 0)
		{
			_year--;
			_month = 12;
		}
		//借天数
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

日期-天数:

//日期 - 天数(	d1 - 100)
Date Date::operator-(int day) 
{	
	//不改d1,拷贝一下
	Date tmp(*this);
	tmp -= day;
	return tmp;
}

日期-日期:

//日期-日期  -
int Date::operator-(const Date& d) 
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	//1.找出较小的日期
	if (*this < min) 
	{
		max = d;
		min = *this;
		flag = -1;
	}
	int n = 0;
	//2.让较小的日期一直+,直到等于较大的日期(加了多少次,它们就差了多少天)
	while (min != max) 
	{
		++min;
		++n;
	}
	//flag用来处理大年减小年或小年减大年的情况
	return n*flag;
	
}

赋值运算符重载(=)

//赋值
void Date::operator=(const Date& x) 
{
	_year = x._year;
	_month = x._month;
	_day = x._day;
}

效果:

C++:日期类_第4张图片

3.前/后置++,--

前/后置++,--会有歧义:

如++运算符重载后的到底是前置++,还是后置++呢?

这里使用函数重载解决,改变形参来区分

C++:日期类_第5张图片

这里说明一下为什么前置可以使用引用返回,后置却不行:

--前置会先改变d1,再++,直接把d1传回去就行了

--后置会先使用原来的,再++,所有要拷贝一份,传回去的是拷贝的tmp,出栈就销毁了,所有不能传引用

++:

//前置++
Date& Date::operator++() 
{
	*this += 1;
	return *this;
}

//后置++
Date Date::operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp; 
}

--:

1

//前置--
Date& Date::operator--() 
{
	*this -= 1;
	return *this;
}

//后置--
Date Date::operator--(int) 
{
	Date tmp(*this);
	*this -= 1;
	return tmp;
}

效果:

C++:日期类_第6张图片

你可能感兴趣的:(C/C++实例,c++,开发语言)