日期类的实现

目录

1.获取某年某月的天数

2.全缺省的构造函数

3. 拷贝构造函数

4.赋值运算符重载

5.析构函数

6.日期+=天数

7.日期+天数

8.日期-天数

9.日期-=天数

10.前置++

11.// 后置++ 

12.后置--

13.前置--

14.>运算符重载

15.==运算符重载

16.>=运算符重载

17.<=运算符重载

18.<运算符重载

19.!=运算符重载

20.日期 - 日期 返回天数

21.流插入

22.流提取


1.获取某年某月的天数

首先要实现一个获取月份天数的函数,要实现是否是闰年或平年,以及二月份的天数

int GetMonthDay(int year, int month);

 获取某年某月的天数
GetMonthDay(int year, int month)
{
	//为了与下标相符合,定义成静态就不用一直创建
	static int arr[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//平年
	if (year % 4 == 0 && year %100 != 0 || year % 400 == 0)//闰年
	{
		arr[2] = 29;
	}
	return arr[month];
}

2.全缺省的构造函数

Date(int year = 1900, int month = 1, int day = 1);

Date(int year = 1900, int month = 1, int day = 1)
{
	_year = year;
	_month = month;
	_day = day;
}

3. 拷贝构造函数

知识点:拷贝构造,内置类型,自定义类型都会处理。默认赋值重载跟拷贝构造一个性质,拷贝构造是定义时,赋值重载是两个已经存在的。

Date(const Date& d)  // d2(d1)

Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

4.赋值运算符重载

知识点:赋值运算符只能重载成类的成员函数不能重载成全局函数

Date& operator=(const Date& d)

Date& operator=(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
	return *this;
}

5.析构函数

知识点:析构函数不能重载,只能删除一次 

 ~Date()

	~Date()
	{
		_year = 0;
		_month = 0;
		_day = 0;
	}

6.日期+=天数

知识点:日期+=天数,+=改变了自身,*this空间没有销毁,所以可以加引用返回

Date& operator+=(int day)

Date& operator+=(int day)
{
	//举例子:4月,_day为10,day是60
	_day = day + _day;
	while (_day > GetMonthDay(_year, _month))
	{
		int i = GetMonthDay(_year, _month);//某年某月的天数
		_day = _day - i;
		++_month;
		if (_month == 13)
		{
			_month = 1;
		}
	}
	return *this;
}

7.日期+天数

Date operator+(int day)

知识点:+和+=一个自身的值变了一个没变,Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值

	Date operator+(int day)
	{
		Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值
		tmp._day = day + tmp._day;
		while (tmp._day > GetMonthDay(tmp._year, tmp._month))
		{
			int i = GetMonthDay(tmp._year, tmp._month);//某年某月的天数
			tmp._day = _day - i;
			tmp._month++;
			if (tmp._month == 13)
			{
				tmp._month = 1;
			}
		}
		return tmp;
	}

8.日期-天数

Date operator-(int day)

Date operator-(int day)
{
	Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值

	//举例子:4月,_day为10,day是60
	tmp._day = tmp._day-day;
	while (tmp._day < 0)
	{
		int i = GetMonthDay(tmp._year, tmp._month-1);//某年某月的天数
		if (tmp._month - 1 == 0)
		{
			tmp._month = 12;
		}
		tmp._day = tmp._day + i;
		tmp._month--;
		if (tmp._month == 0)
		{
			tmp._month = 12;
		}
	}
	return tmp;
}

9.日期-=天数

Date& operator-=(int day)

// 日期-=天数
Date& operator-=(int day)
{
	//举例子:4月,_day为10,day是60
	_day = _day - day;
	while (_day < 0)
	{
		int i = GetMonthDay(_year, _month - 1);//某年某月的天数
		if (_month - 1 == 0)
		{
			_month = 12;
		}
		_day = _day + i;
		_month--;
		if (_month == 0)
		{
			_month = 12;
		}
	}
	return *this;
}

10.前置++

Date& operator++()

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

11.// 后置++ 

知识点:// 后置++,后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1

// 后置++,后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1
Date operator++(int)
{
	Date temp(*this);
	*this += 1;
	return temp;
}

区别:一个不改变自己的值,一个改变,后置括号里有int,前置没有

12.后置--

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

13.前置--

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

14.>运算符重载

内置类型可以直接比较,而自定义类型不能直接比较,要用运算符重载

技巧:先写一个大于一个等于,其他的直接!就好了

bool operator>(const Date& d) const
{
	if (_day > d._day && _month >= d._month && _year >= d._year)
	{
		return true;
	}

	else if (_day < d._day && _month >= d._month && _year >= d._year)
	{
		return true;
	}

	else if (_day < d._day && _month <= d._month && _year > d._year)
	{
		return true;
	}
	else
	{
		return false;
	}
}

15.==运算符重载

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

16.>=运算符重载

bool operator >= (const Date& d)
{
	return *this > d || *this == d;
}

17.<=运算符重载

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

18.<运算符重载

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

19.!=运算符重载

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

20.日期 - 日期 返回天数

int operator-(const Date& d)
{
	Date max = *this;
	Date min = d;
	int n = 0;//定义相差天数
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	while (min != max)
	{
		min++;
		++n;
	}
	return flag * n;
}

21.流插入

知识点:流插入流提取只能写在类外,因为需要两个接收值,要是在类内就会有隐藏的this指针,要用friend,友元函数声明

ostream& operator<<(ostream& out, const Date& d);//ostream前不能加const,d不可被修改必须加

ostream& operator<<(ostream& out, const Date& d)//ostream前不能加const,d不可被修改必须加
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out; 
}

22.流提取

istream& operator>>(istream& in,  Date& d)//不支持写const

istream& operator>>(istream& in,  Date& d)//不支持写const
{
	in >> d._year >> d._month >> d._day;
	return in;
}

23.总代码

#include<iostream>
using namespace std;
class Date
{
	//单个友元函数声明,为了访问private中的数据,不写访问不到
	//friend void operator<<(ostream& out, const Date& d);

	//多个友元函数声明,为了访问private中的数据,不写访问不到
	friend  ostream& operator<<(ostream& out, const Date& d);

	//流提取
	friend istream& operator>>(istream& out, Date& d);//

public:
	// 获取某年某月的天数
	int GetMonthDay(int year, int month)
	{
		//为了与下标相符合,定义成静态就不用一直创建
		static int arr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//平年
		if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//闰年
		{
			arr[2] = 29;
		}
			return arr[month];
	}

	// 全缺省的构造函数
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	

	// 拷贝构造函数
  // d2(d1)
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

	// 赋值运算符重载,赋值运算符只能重载成类的成员函数不能重载成全局函数
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}

	// 析构函数
	~Date()
	{
		_year = 0;
		_month = 0;
		_day = 0;
	}

	// 日期+=天数,+=改变了自身,*this空间没有销毁,所以可以加引用返回
	Date& operator+=(int day)
	{
		//举例子:4月,_day为10,day是60
		_day = day + _day;
		while (_day > GetMonthDay(_year, _month))
		{
			int i = GetMonthDay(_year, _month);//某年某月的天数
			_day = _day - i;
			++_month;
			if (_month == 13)
			{
				_month = 1;
			}
		}
		return *this;
	}

	// 日期+天数
	Date operator+(int day)
	{
		Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值
		tmp._day = day + tmp._day;
		while (tmp._day > GetMonthDay(tmp._year, tmp._month))
		{
			int i = GetMonthDay(tmp._year, tmp._month);//某年某月的天数
			tmp._day = _day - i;
			tmp._month++;
			if (tmp._month == 13)
			{
				tmp._month = 1;
			}
		}
		return tmp;
	}

	// 日期-天数
	Date operator-(int day)
	{
		Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值

		//举例子:4月,_day为10,day是60
		tmp._day = tmp._day-day;
		while (tmp._day < 0)
		{
			int i = GetMonthDay(tmp._year, tmp._month-1);//某年某月的天数
			if (tmp._month - 1 == 0)
			{
				tmp._month = 12;
			}
			tmp._day = tmp._day + i;
			tmp._month--;
			if (tmp._month == 0)
			{
				tmp._month = 12;
			}
		}
		return tmp;
	}

	// 日期-=天数
	Date& operator-=(int day)
	{
		//举例子:4月,_day为10,day是60
		_day = _day - day;
		while (_day < 0)
		{
			int i = GetMonthDay(_year, _month - 1);//某年某月的天数
			if (_month - 1 == 0)
			{
				_month = 12;
			}
			_day = _day + i;
			_month--;
			if (_month == 0)
			{
				_month = 12;
			}
		}
		return *this;
	}

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

	// 后置++,后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1
	Date operator++(int)
	{
		Date temp(*this);
		*this += 1;
		return temp;
	}

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

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

	// >运算符重载
	bool operator>(const Date& d) const
	{
		if (_day > d._day && _month >= d._month && _year >= d._year)
		{
			return true;
		}

		else if (_day < d._day && _month >= d._month && _year >= d._year)
		{
			return true;
		}

		else if (_day < d._day && _month <= d._month && _year > d._year)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	// ==运算符重载
	bool operator==(const Date& d)
	{
		return _year == d._year && _month == d._month && _day == d._day;
	}

	// >=运算符重载
	bool operator >= (const Date& d)
	{
		return *this > d || *this == d;
	}
	
	// <=运算符重载
	bool operator <= (const Date& d)
	{
		return !(*this > d);
	}

	// <运算符重载
	bool operator < (const Date& d)
	{
		return !(*this >= d);
	}

	// !=运算符重载
	bool operator != (const Date& d)
	{
		return !(*this == d);
	}

	// 日期-日期 返回天数
	//int operator-(const Date& d)
	//{
	//	//举例子:1990年4月20,和1993年5月28,假设*this小
	//	if (*this < d)
	//	{
	//		//this的总天数(不带年的)
	//		int sum = 0; int t = _month-1;
	//		while (t--)
	//		{
	//			int i = GetMonthDay(_year, t);//*this的
	//			sum = sum + i;
	//		}
	//		sum = sum + _day;
	//		//d的
	//		int sum1 = 0; int t1 = d._month-1;
	//		while (t1--)
	//		{
	//			int i = GetMonthDay(d._year, t1);//d的
	//			sum1 = sum1 + i;
	//		}
	//		sum1 = sum1 + d._day;
	//		return sum1 - sum;
	//		//int rs = 0;
	//		//if (d._year - _year==1)
	//		//{
	//		//	if (_year % 4 == 0 && _year % 100 != 0 || _year % 400 == 0)//闰年
	//		//	{
	//		//		int rs = 366;//this是闰年,则天数为366天
	//		//	}
	//		//}
	//		//else
	//		//{

	//		//}
	//		//int k = rs - sum;//this减去this日期剩的天数
	//		//return k + sum1;	
	//	}
	//}
	//日期 - 日期 返回天数
	//2003 10月10日  举例子
//2002 9月10日
	int operator-(const Date& d)
	{
		Date max = *this;
		Date min = d;
		int n = 0;//定义相差天数
		int flag = 1;
		if (*this < d)
		{
			max = d;
			min = *this;
			flag = -1;
		}
		while (min != max)
		{
			min++;
			++n;
		}
		return flag * n;
	}

	void print()const
	{
		cout << _year << " " << _month << "  " << _day << endl;
	}

private:

	int _year;
	int _month;
	int _day;
};
//单个流插入声明
//void operator<<(ostream& out, const Date& d);
// 
// 
//多个流插入声明
ostream& operator<<(ostream& out, const Date& d);//ostream前不能加const,d不可被修改必须加

//流提取
istream& operator>>(istream& out,  Date& d);//


//多个流插入
ostream& operator<<(ostream& out, const Date& d)//ostream前不能加const,d不可被修改必须加
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out; 
}

//流提取
istream& operator>>(istream& in,  Date& d)//不支持写const
{
	in >> d._year >> d._month >> d._day;
	return in;
}


 test(重要知识点)

Date d3(1900, 2, 1);
连续的流插入,需要有返回值,跟内置类型差不多
cout << d2 << d1 << d3;//d2先流入


int main()
{
	/*Date d1(1900, 7, 20);
	Date d2(1900, 5, 29);*/

	/*d1 + 40;
	d1.print();*///结果还是d1,因为是加没有改变d1本身
	//d1 += 40;
	//d1.print();//这个才是

	//d1 -= 60;
	//d1.print();

	//int i=(d1 == d2) ;
	///*printf("%d", i);*/
	//cout << (d1 == d2) << endl;

	//cout << (d2 > d1) << endl;

	//cout << (d2 <= d1) << endl;

	//cout << (d1 - d2)<<endl;

	//cout << d1;//两个等价
	//operator<<(cout, d1);


	//Date d3(1900, 2, 1);
	连续的流插入,需要有返回值,跟内置类型差不多
	//cout << d2 << d1 << d3;//d2先流入

	流提取
	//cin >> d2 >> d1;

	//cout<< d2 << d1;

	const Date d6(1900, 9, 9);
	d6.print();//不能这样调用,要在print处加上const,但是不带const的照样打印,可以缩小权限,但不能放大
	Date d7(1900, 9, 9);
	d7.print();

	d7 > d6;//可以担d6>d7不可以,operator接受的时候,const在右边,在左边也加上const,d6>d7才能实现
	d6 > d7;//不改变值的都可以加上const

	return 0;
}

  • 84
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 23
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值