C++日期类实现(联系类和对象)

目录

一.6个默认成员函数

二.基本功能函数

三.日期与天数的加减

四.前后置++和--

五.比较运算符重载

六.日期减日期

七.全部代码

        1.Date.h

        2.Date.cpp


C++初学者都可以在学习完类和对象后写一个日期类,以下是实现细节。

一.6个默认成员函数

        对于日期类默认成员函数使用编译器生成的足矣,这里就不多赘述。

        提醒一下对于赋值运算符重载需要判断是不是自己给自己赋值。

二.基本功能函数

        对于我们实现日期+-天数有用的基本功能函数。

        1.GetMonthDay(返回对应月份的天数,也考虑了闰年二月天数变化)

// 获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{
	static int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//数组扩大1下标就不用-1了
	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))//判断闰年
		return arr[month] + 1;
	return arr[month];
}

        2.Judge(判断月份是否合法)

//判断日期是否合法
bool Date::judge()
{
	if (_month <= 12 && _month > 0 && _day <= GetMonthDay(_year, _month) && (_day > 0))//判断月份和天数是不是正常的
		return true;
	return false;
}

        3.Print(输出日期)

//输出日期
void Date::Print()
{
	cout << _year << " " << _month << " " << _day << endl;
}

三.日期与天数的加减

        我们可以实现+=和-=的功能,然后+和-分别复用+=和-=的功能。

        1.+=和+

// 日期+=天数
Date& Date::operator+=(int day)//可以理解为让日期一个月一个月往前走
{
	_day += day;//直接把天数加上去
	while (!judge())//一直对日期进行处理,直到合法为止
	{
		_day -= GetMonthDay(_year, _month);//这里注意_day是先减_month是后++的
		_month++;
		if (_month == 13)//月份越界就让年份加1,相当于月份变为下一年的1月
		{
			_year++;
			_month = 1;
		}
	}
	return *this;//引用返回就直接返回*this
}

// 日期+天数
Date Date::operator+(int day)
{
	Date tmp(*this);//创建临时对象
	tmp += day;//复用+=
	return tmp;//不是引用返回所以是返回临时对象
}

        2.-=和-

// 日期-=天数
Date& Date::operator-=(int day)//可以理解让日期一个月一个月往后退
{
	_day -= day;//和+=一样直接让_day减day
	while (!judge())//一直对日期处理直到合法为止
	{
		_month--;
		if (_month == 0)//月份非法就让year-1,相当于是到了去年的12月
		{
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);//注意这里是月份先减1,然后才加天数,和+=是相反的
	}
	return *this;//引用返回所以是返回*this
}

// 日期-天数
Date Date::operator-(int day)
{
	Date tmp(*this);//创建临时对象
	tmp -= day;//复用-=
	return tmp;//不是引用返回所以是返回临时对象
}

四.前后置++和--

        ++和--复用+=和-=就可以,需要注意的是前置和后置在函数原型上的区别。

        1.++

// 前置++
Date& Date::operator++()
{
	*this += 1;//复用+=
	return *this;//注意是引用返回
}

// 后置++
Date Date::operator++(int)//后置++需要在参数表加一个int用来占位,用来区分前后置++,编译器会进行特殊处理
{
	++(*this);//自身也要++
	Date tmp(*this);//创建临时对象
	return tmp;//注意事项传值返回
}

        2.--

// 前置--
Date& Date::operator--()
{
	*this -= 1;//复用-=
	return *this;//注意是引用返回
}

// 后置--
Date Date::operator--(int)//后置--需要在参数表加一个int用来占位,用来区分前后置--,编译器会进行特殊处理
{
	--(*this);//自身也要--
	Date tmp(*this);//创建临时对象
	return tmp;//注意事项传值返回
}

五.比较运算符重载

        只需要实现==和>或<,其他的比较运算符复用前两个就行。

// >运算符重载
bool Date::operator>(const 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==(const Date& d)
{
	if (_year == d._year && _month == d._month && _day == d._day)//全部都一样就返回true
		return true;
	return false;
}
// >=运算符重载
bool Date::operator >= (const Date& d)
{
	return *this > d || *this == d;//>=就是>或者==
}
// <运算符重载
bool Date::operator < (const Date& d)
{
	return !(*this > d || *this == d);//<就是>=的取反
}
// <=运算符重载
bool Date::operator <= (const Date& d)
{
	return !(*this > d);//<=就是>的取反
}
// !=运算符重载
bool Date::operator != (const Date& d)
{
	return !(*this == d);//!=就是==的取反
}

六.日期减日期

        日期-日期的实现方式有很多,我们这里直接用暴力,就是用小日期一直++天数,直到等于大的日期为止(优化版本就是按月来算)。另一种方式是让两个日期都对一个小的日期计算天数,然后再相减(不用判断谁大谁小)。

// 日期-日期 返回天数
int Date::operator-(const Date& d)
{
	Date tmp, target;//用两个临时变量计算
	int day = 0, flag = 0;//day是计算天数,flag是判断*this是否小于d
	if (*this < d)
	{
		flag = 1;//*this小于d,令flag=1
		tmp = (*this);//tmp默认是小的日期
		target = (d);//target默认是大的日期
	}
	else
	{
		tmp = (d);//tmp默认是小的日期
		target = (*this);//target默认是大的日期
	}
	while (tmp != target)//两个日期不相等就一直处理
	{
		tmp++;//小日期++
		day++;//计算天数差值
	}
	if (flag)//如果*this小于d,那么天数差值就是负数
		day *= -1;
	return day;
}

七.全部代码

        1.Date.h

#pragma once
class Date
{
public:

	// 获取某年某月的天数
	int GetMonthDay(int year, int month);

	//判断日期是否合法
	bool judge();

	//输出日期
	void Print();

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

	// 拷贝构造函数
	// d2(d1)
	Date(const Date& d);

	// 赋值运算符重载
	// d2 = d3 -> d2.operator=(&d2, d3)
	Date& operator=(const Date& d);

	// 析构函数
	~Date();

	// 日期+=天数
	Date& operator+=(int day);

	// 日期+天数
	Date operator+(int day);

	// 日期-天数
	Date operator-(int day);

	// 日期-=天数
	Date& operator-=(int day);

	// 前置++
	Date& operator++();

	// 后置++
	Date operator++(int);

	// 后置--
	Date operator--(int);

	// 前置--
	Date& operator--();

	// >运算符重载
	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);

	// 日期-日期 返回天数
	int operator-(const Date& d);

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

        2.Date.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include"Date.h"
using namespace std;

// 获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{
	static int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//数组扩大1下标就不用-1了
	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))//判断闰年
		return arr[month] + 1;
	return arr[month];
}

//判断日期是否合法
bool Date::judge()
{
	if (_month <= 12 && _month > 0 && _day <= GetMonthDay(_year, _month) && (_day > 0))//判断月份和天数是不是正常的
		return true;
	return false;
}

//输出日期
void Date::Print()
{
	cout << _year << " " << _month << " " << _day << endl;
}

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

// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& Date::operator=(const Date& d)
{
	if (&d != this)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}
}

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

// 日期+=天数
Date& Date::operator+=(int day)//可以理解为让日期一个月一个月往前走
{
	_day += day;//直接把天数加上去
	while (!judge())//一直对日期进行处理,直到合法为止
	{
		_day -= GetMonthDay(_year, _month);//这里注意_day是先减_month是后++的
		_month++;
		if (_month == 13)//月份越界就让年份加1,相当于月份变为下一年的1月
		{
			_year++;
			_month = 1;
		}
	}
	return *this;//引用返回就直接返回*this
}

// 日期+天数
Date Date::operator+(int day)
{
	Date tmp(*this);//创建临时对象
	tmp += day;//复用+=
	return tmp;//不是引用返回所以是返回临时对象
}

// 日期-天数
Date Date::operator-(int day)
{
	Date tmp(*this);//创建临时对象
	tmp -= day;//复用-=
	return tmp;//不是引用返回所以是返回临时对象
}

// 日期-=天数
Date& Date::operator-=(int day)//可以理解让日期一个月一个月往后退
{
	_day -= day;//和+=一样直接让_day减day
	while (!judge())//一直对日期处理直到合法为止
	{
		_month--;
		if (_month == 0)//月份非法就让year-1,相当于是到了去年的12月
		{
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);//注意这里是月份先减1,然后才加天数,和+=是相反的
	}
	return *this;//引用返回所以是返回*this
}

// 前置++
Date& Date::operator++()
{
	*this += 1;//复用+=
	return *this;//注意是引用返回
}

// 后置++
Date Date::operator++(int)//后置++需要在参数表加一个int用来占位,用来区分前后置++,编译器会进行特殊处理
{
	++(*this);//自身也要++
	Date tmp(*this);//创建临时对象
	return tmp;//注意事项传值返回
}

// 后置--
Date Date::operator--(int)//后置--需要在参数表加一个int用来占位,用来区分前后置--,编译器会进行特殊处理
{
	--(*this);//自身也要--
	Date tmp(*this);//创建临时对象
	return tmp;//注意事项传值返回
}

// 前置--
Date& Date::operator--()
{
	*this -= 1;//复用-=
	return *this;//注意是引用返回
}

// >运算符重载
bool Date::operator>(const 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==(const Date& d)
{
	if (_year == d._year && _month == d._month && _day == d._day)//全部都一样就返回true
		return true;
	return false;
}
// >=运算符重载
bool Date::operator >= (const Date& d)
{
	return *this > d || *this == d;//>=就是>或者==
}
// <运算符重载
bool Date::operator < (const Date& d)
{
	return !(*this > d || *this == d);//<就是>=的取反
}
// <=运算符重载
bool Date::operator <= (const Date& d)
{
	return !(*this > d);//<=就是>的取反
}
// !=运算符重载
bool Date::operator != (const Date& d)
{
	return !(*this == d);//!=就是==的取反
}

// 日期-日期 返回天数
int Date::operator-(const Date& d)
{
	Date tmp, target;//用两个临时变量计算
	int day = 0, flag = 0;//day是计算天数,flag是判断*this是否小于d
	if (*this < d)
	{
		flag = 1;//*this小于d,令flag=1
		tmp = (*this);//tmp默认是小的日期
		target = (d);//target默认是大的日期
	}
	else
	{
		tmp = (d);//tmp默认是小的日期
		target = (*this);//target默认是大的日期
	}
	while (tmp != target)//两个日期不相等就一直处理
	{
		tmp++;//小日期++
		day++;//计算天数差值
	}
	if (flag)//如果*this小于d,那么天数差值就是负数
		day *= -1;
	return day;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值