当前位置: 首页 > article >正文

C++运算符重载的使用——实现日期类

目录

一、声明头文件

二、函数实现

        0、cout 输出类

        1、cin读取类

        2、实现获取某年某月的天数

        3、实现全缺省的构造函数

        4、实现赋值运算符重载

        5、实现日期+=天数

        6、实现日期+天数

        7、实现日期-=天数

        8、实现日期-天数

        9、实现后置++

        10、实现前置++

        11、实现后置--

        12、实现前置--

        13、实现!=运算符重载

        14、实现==运算符重载

        15、实现>运算符重载

        16、实现>=运算符重载

        17、实现<运算符重载

        18、实现<=运算符重载

        19、得到一个日期从0年0月0日到当前日期的天数 

        20、实现日期-日期


一、声明头文件

        声明日期类需要实现的函数


//声明日期类
class Date
{
	//声明友元
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
	//打印日期
	void print();

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

	// 全缺省的构造函数
	Date(int year = 1, int month = 1, int day = 1);

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

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

	//得到一个日期从0年0月0日到当前日期的天数
	int GetTotal();

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

private:
	//年
	int _year;
	//月
	int _month;
	//日
	int _day;
};
// cout 输出类
ostream& operator<<(ostream& out, const Date& d);
// cin 读取类
istream& operator>>(istream& in, Date& d);

二、函数实现

        0、cout 输出类

        由于【cout】本身不支持输出自定义类型,因此这里首先实现【cout】 运算符重载。方便后面的测试

【注意】

        这里已经在类中声明了友元函数,因此可以实现为全局函数

// cout 输出类
void operator<<(ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day << endl;
}

        1、cin读取类

【注意】

        这里已经在类中声明了友元函数,因此可以实现为全局函数

// cin 读取类
istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

         2、实现获取某年某月的天数

        由于日期的计算需要考虑到很多因素(平年、闰年、大月,小月),因此这里实现一个获取某年某月的天数的函数。方便后续函数的计算

//实现获取某年某月的天数
int Date::GetMonthDay(int year, int month) 
{
	int arr[] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
	{
		arr[2]++;
	}
	return arr[month];
}

        3、实现全缺省的构造函数

        这里我默认的是1年1月1日 

【注意】

        因为这里展示的函数声明与函数定义的分开实现,而缺省值只能在声明时实现,因此这里的定义就没有写缺省值了

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

        4、实现赋值运算符重载

        返回值类型为【Date&】类型是为了支持连续赋值

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

        5、实现日期+=天数

Date& Date::operator+=(int day)
{
	//如果日期为负数,改为使用【-=】
	if (day < 0)
	{
		return *this -= day;
	}
	//加上当前日期
	_day += day;
	int num = GetMonthDay(_year, _month);
	//判断当前天数是否满足当前月份的天数
	while (_day > num)
	{
		//月份进一
		_month++;
		//月份大于12,年份进一
		if (_month > 12)
		{
			_month = 1;
			_year++;
		}
		_day -= num;
		//更新当前月份的天数
		num = GetMonthDay(_year, _month);
	}
	return *this;
}

        考虑复用:由于【+=】与【+】的运算逻辑高度相似,因此可以考虑复用

//考虑复用
Date& Date::operator+=(int day)
{
	//复用【+】运算符重载
	*this = *this + day;
	return *this;
}

        6、实现日期+天数

// 实现日期+天数
Date Date::operator+(int day)
{
	//创建临时变量,【+】运算符不改变自己
	Date tmp = *this;
	//加上当前日期
	tmp._day += day;
	int num = GetMonthDay(_year, _month);
	//判断当前天数是否满足当前月份的天数
	while (tmp._day > num)
	{
		//月份进一
		tmp._month++;
		//月份大于12,年份进一
		if (tmp._month > 12)
		{
			tmp._month = 1;
			tmp._year++;
		}
		tmp._day -= num;
		//更新当前月份的天数
		num = GetMonthDay(tmp._year, tmp._month);
	}
	return tmp;
}

        考虑复用:由于【+】与【+=】的运算逻辑高度相似,因此可以考虑复用 

//考虑复用
Date Date::operator+(int day)
{
	if (day < 0)
	{
		return *this + day;
	}
	Date tmp = *this;
	//复用【+=】运算符
	tmp += day;
	return tmp;
}

        7、实现日期-=天数

// 实现日期-=天数
Date& Date::operator-=(int day) {
	//减去指定天数
	_day -= day;
	//判断当前天数是否满足当前月份的天数
	while (_day <= 0)
	{
		//月份减一
		_month--;
		//月份小于1,年份减一
		if (_month <= 0)
		{
			_month = 12;
			_year--;
		}
		//获取当前月份的天数
		int num = GetMonthDay(_year, _month);
		//更新当前天数
		_day += num;
	}
	return *this;
}

        考虑复用:由于【-=】与【-】的运算逻辑高度相似,因此可以考虑复用

//考虑复用
Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return *this -= day;
	}
	//复用【-】运算符
	*this = *this - day;
	return *this;
}

        8、实现日期-天数

// 实现日期-天数
Date Date::operator-(int day)
{
	if (day < 0)
	{
		return *this + day;
	}
	//创建临时变量,【-】运算符不改变自己
	Date tmp = *this;
	//减去指定天数
	tmp._day -= day;
	//判断当前天数是否满足当前月份的天数
	while (tmp._day <= 0)
	{
		//月份减一
		tmp._month--;
		//月份小于1,年份减一
		if (tmp._month <= 0)
		{
			tmp._month = 12;
			tmp._year--;
		}
		//获取当前月份的天数
		int num = tmp.GetMonthDay(tmp._year, tmp._month);
		//更新当前天数
		tmp._day += num;
	}
	return tmp;
}

        考虑复用:由于【-】与【-=】的运算逻辑高度相似,因此可以考虑复用 

//考虑复用
Date Date::operator-(int day)
{
	if (day < 0)
	{
		return *this + day;
	}
	Date tmp = *this;
	//复用【-=】运算符
	tmp -= day;
	return tmp;
}

        9、实现后置++

        后置++重载时,增加⼀个【int】形参,跟前置++构成函数重载,⽅便区分

// 后置++
Date Date::operator++(int)
{
	//创建临时变量,后置【++】运算符先赋值后加1
	Date tmp = *this;
	//日期加1
	_day += 1;
	//获取当前月份的天数
	int num = GetMonthDay(_year, _month);
	//判断当前天数是否满足当前月份的天数
	while (_day > num)
	{
		//月份进一
		_month++;
		//月份大于12,年份进一
		if (_month > 12)
		{
			_month = 1;
			_year++;
		}
		_day -= num;
		//更新当前月份的天数
		num = GetMonthDay(_year, _month);
	}
	return tmp;
}

        考虑复用:由于【++】就是本身加1,因此可以考虑复用【+=】

Date Date::operator++(int)
{
	Date tmp = *this;
    //考虑复用
	*this += 1;
	return tmp;
}

        10、实现前置++

        前置【++】不用增加⼀个【int】形参

// 实现前置++
Date& Date::operator++()
{
	//日期加1
	_day += 1;
	//获取当前月份的天数
	int num = GetMonthDay(_year, _month);
	//判断当前天数是否满足当前月份的天数
	while (_day > num)
	{
		//月份进一
		_month++;
		//月份大于12,年份进一
		if (_month > 12)
		{
			_month = 1;
			_year++;
		}
		_day -= num;
		//更新当前月份的天数
		num = GetMonthDay(_year, _month);
	}
	return *this;
}

         考虑复用:由于【++】就是本身加1,因此可以考虑复用【+=】

Date& Date::operator++()
{
	//考虑复用
	*this += 1;
	return *this;
}

        11、实现后置--

         后置【--】重载时,增加⼀个【int】形参,跟前置++构成函数重载,⽅便区分 

// 实现后置--
Date Date::operator--(int)
{
	//创建临时变量,后置【--】运算符先赋值后减1
	Date tmp = *this;
	//日期减1
	_day -= 1;
	//判断当前天数是否满足当前月份的天数
	while (_day <= 0)
	{
		//月份减一
		_month--;
		//月份小于1,年份减一
		if (_month <= 0)
		{
			_month = 12;
			_year--;
		}
		//获取当前月份的天数
		int num = GetMonthDay(_year, _month);
		//更新当前天数
		_day += num;
	}
	return tmp;
}

        考虑复用:由于【--】就是本身减1,因此可以考虑复用【-=】

Date Date::operator--(int)
{
	//创建临时变量,后置【--】运算符先赋值后减1
	Date tmp = *this;
	//考虑复用
	*this -= 1;
	return tmp;
}

         12、实现前置--

        前置【--】不用增加⼀个【int】形参

// 实现前置--
Date& Date::operator--()
{
	//日期减1
	_day -= 1;
	//判断当前天数是否满足当前月份的天数
	while (_day <= 0)
	{
		//月份减一
		_month--;
		//月份小于1,年份减一
		if (_month <= 0)
		{
			_month = 12;
			_year--;
		}
		//获取当前月份的天数
		int num = GetMonthDay(_year, _month);
		//更新当前天数
		_day += num;
	}
	return *this;
}

        考虑复用:由于【--】就是本身减1,因此可以考虑复用【-=】

Date& Date::operator--()
{
	//考虑复用
	*this -= 1;
	return *this;
}

        13、实现!=运算符重载

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

        考虑复用:【==】运算符取反就是【!=】 

bool Date::operator != (const Date& d)
{
	//【==】运算符取反就是【!=】 
	return !(*this == d);
}

        14、实现==运算符重载

bool Date::operator==(const Date& d)
{
	//年
	if (_year != d._year)
		return false;
	//月
	if (_month != d._month)
		return false;
	//日
	if (_day != d._day)
		return false;
	return true;
}

         考虑复用:【!=】运算符取反就是【==】 

bool Date::operator==(const Date& d) {
	//【!=】运算符取反就是【==】 
	return !(*this != d);
}

        15、实现>运算符重载

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

        考虑复用:【<=】运算符取反就是【>】  

bool Date::operator>(const Date& d)
{
	//【<=】运算符取反就是【>】  
	return !(*this <= d);
}

        16、实现>=运算符重载

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

        考虑复用:【<】运算符取反就是【>=】

bool Date::operator >= (const Date& d)
{
	//【<】运算符取反就是【>=】
	return !(*this < d);
}

        考虑复用:【==】和【>】运算符,只要有一个为真,那么整体就为真。   【==】和【>】运算符,都为假,那么整体就为假

bool Date::operator >= (const Date& d)
{
	//复用【==】和【>】
	if (*this == d || *this > d)
	{
		return true;
	}
	return false;
}

        17、实现<运算符重载

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

        考虑复用:【>=】运算符取反就是【<】 

bool Date::operator < (const Date& d)
{
	//【>=】运算符取反就是【<】 
	return !(*this >= d);
}

        18、实现<=运算符重载

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

        考虑复用:【>】运算符取反就是【<=】  

bool Date::operator <= (const Date& d)
{
	//【>】运算符取反就是【<=】  
	return !(*this > d);
}

        考虑复用:【==】和【<】运算符,只要有一个为真,那么整体就为真。   【==】和【<】运算符,都为假,那么整体就为假

bool Date::operator <= (const Date& d)
{
	//复用【==】和【>】
	if (*this == d || *this < d)
	{
		return true;
	}
	return false;
}

        19、得到一个日期从0年0月0日到当前日期的天数 

        这函数的逻辑牵扯到一些数学逻辑,有兴趣的可以去了解一下

        这里我们只需要知道这个函数将返回一个日期从0年0月0日到当前日期的天数 

int Date::GetTotal()
{
	Date tmp = *this;
	if (tmp._month < 3) {
		--tmp._year;
		tmp._month += 12;
	}
	return 365 * tmp._year + tmp._year / 4 - tmp._year / 100 + tmp._year / 400 + (153 * tmp._month - 457) / 5 + tmp._day - 306;
}

        20、实现日期-日期

        【日期 - 日期】得到的是两个日期之间相差的天数

// 实现日期-日期
int Date::operator-(const Date& d)
{
	Date tmp = d;
	return GetTotal() - tmp.GetTotal();
}


http://www.kler.cn/a/429147.html

相关文章:

  • 编程工具箱(免费,离线可用)
  • Navicat 17 功能简介 | 商业智能 BI
  • 函数(函数的概念、库函数、自定义函数、形参和实参、return语句、数组做函数参数、嵌套调用和链式访问、函数的声明和定义、static和extern)
  • 职场沟通与行为
  • Linux操作命令之云计算基础命令
  • Windows重装后NI板卡LabVIEW恢复正常
  • Leaflet Marker的突出显示,以及聚合
  • 医院专家抽取系统——未来之窗行业应用跨平台架构
  • Android开发-----Could not install Gradle distribution from- gradle
  • 在 Windows WSL 上部署 Ollama 和大语言模型:从镜像冗余问题看 Docker 最佳实践20241208
  • 泷羽sec学习打卡-brupsuite4
  • 高级数据结构-树状数组
  • Halcon_数据类型_ROI_仿射变换_投影变换
  • 设计模式 在SCM系统的应用场景介绍
  • ISO45001职业健康安全管理体系认证流程
  • springboot整合lua脚本在Redis实现商品库存扣减
  • 关系型数据库(RDBMS)和非关系型数据库(NoSQL)
  • 使用 Trace 实现 onnx 的导出 - 学习记录
  • golang学习,小结
  • 数学公式和科学符号在页面的展示方法
  • 去除背景 学习笔记
  • PCB设计规范
  • 运维监控grafana+prometheus+node_exporter(or mysqld_exporter)
  • 手动将MJPEG图片,转成MP4文件格式
  • centOS7如何配置阿里云或者腾讯云yum源
  • 【Linux】搭建临时HTTP文件传输服务器