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

9.C++面向对象6(实现一个较为完善的日期类)

⭐本篇重点:const成员变量和函数,取地址重载

⭐本篇代码:c++学习/02.c++面向对象-中/2.实现完善的日期类 · 橘子真甜/c++-learning-of-yzc - 码云 - 开源中国 (gitee.com)

目录

一. 日期类分析

二. 代码实现   

2.1 构造函数

2.2 拷贝构造

2.3 析构函数

2.4 赋值运算符重载

2.5 比较运算重载

2.6 加减法运算符重载

2.7 自增自减运算符重载

一. 日期类分析

        我们想要实现一个完善的日期类,首先要有基本的构造函数,析构函数,拷贝构造函数,赋值运算符重载。

        我们在日常生活中对日期的操作有,一个日期去加减某个天数获得另一个日期,比较两个日期(大于,小于,等于)。没有乘法除法(对于日期来说没有意义)

        根据分析,我们能够很快写出成员函数和成员变量的基本框架。

class Date
{
public:
	//构造函数
	Date(int year = 0, int month = 0, int day = 0)
	{}

	//析构函数
	~Date()
	{}

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

	//赋值运算符重载
	Date& 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
	{}

	//大于等于
	bool operator>=(const Date& d)const
	{}

	//加减操作

	//加等
	Date& operator+=(int day)
	{}

	//加
	Date& operator+(int day)
	{}

	//减等
	Date& operator-=(int day)
	{}

	//减
	Date& operator-(int day)
	{}

	//前置++,++d1
	Date& operator++()
	{}

	//后置++,d1++,后置++我们在函数参数中用一个int进行标识,这是c++的约定
	Date& operator++(int)
	{}

	//前置--,--d1
	Date& operator--()
	{}

	//后置--,d1--
	Date& operator--(int)
	{}
private:
	int _year;
	int _month;
	int _day;
};

二. 代码实现   

2.1 构造函数

        我们知道一年有12个月,每个月都有自己的天数,那么用户输入的年,月,日就一定要合法。如果输入不合法就向用户显示报错。

        年份和月份都很好判断,年份:不是负数就行。月份:1<= m <=12。

        比较难判断的是日期,每月的天数不一样且有闰年存在,所以我们需要定义一个函数来获取某年某月的天数范围。

该函数代码如下:

	//获取某年某月的最大天数
    int GetMonthDay(const int& year, const int& month)
	{
		static int MonthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//每月的天数
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
		{
			return 29;
		}

		return MonthDays[month];
	}

因此构造函数如下


	//构造函数
	Date(int year = 0, int month = 0, int day = 0)
	{
		if (year >= 0 && month >= 0 && month <= 12 && day <= GetMonthDay(year, month))
		{
			_year = year;
			_month = month;
			_day = day;
		}
		else
		{
			cout << "输入非法日期" << endl;
			_year = _month = _day = -999999;
		}
	}

2.2 拷贝构造

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

2.3 析构函数

无动态分配内存,不需要释放空间

//析构函数
	~Date()
	{}

2.4 赋值运算符重载

为了支持 d1 = d2 = d3这种操作,我们需要使用引用返回(见赋值运算符重载)

	//赋值运算符重载
	Date& operator=(const Date& d)
	{
		if (this != &d)//this和d不同的情况下才能赋值
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}

		return *this;	//引用返回不能返回临时变量
	}

2.5 比较运算重载

小于

年份小一定小,年份相等,月份小一定小,年月相等,日小一定小

	//小于,定义为const函数
	bool 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;
		return false;
	}

等于

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

有了小于运算符重载和等于运算符重载,我们可以调用这个函数完成其他比较(函数复用)

小于等于

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

大于

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

大于等于

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

不等于

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

2.6 加减法运算符重载

加减法是用于两个日期相加吗??

2024/11/12 + 2024/11/13 没有意义所以我们实现的加减法都是一个日期去加减一个天数

如: 2024/11/12 + 1 

我们首先实现+=这个操作符和-=

        我们直接将合法day加入到这个日期的_day中,然后循环判断其值是否大于这年这月的天数,如果大于让其减去这个月的天数然后让_month++,如果_month大于12说明要进位年,_year++,_month-=12即可

+=

	//加等
	Date& operator+=(int day)
	{
		if (day < 0)
		{
			day -= (-1 * day);
		}
		else
		{
			_day += day;
			while (_day > GetMonthDay(_year, _month))
			{
				day -= GetMonthDay(_year, _month);
				_month++;

				if (_month >= 13)
				{
					_month -= 12;
					_year++;
				}
			}
		}
		return *this;
	}

-=也是类似的思路

//减等
	Date& operator-=(int day)
	{
		if (day > 0)
		{
			day -= (-1 * day);
		}
		else
		{
			_day -= day;
			while (_day <= 0)
			{
				_month--;

				if (_month == 0)
				{
					_year--;//月份为0,说明年份要-1
					_month = 12;//月份回到早一年的12
				}
				_day += GetMonthDay(_year, _month);
			}
		}
		return *this;
	}

实现了+=和-=我们就能够用这两个重载去实现+和-        (实现对函数的复用)

+

注意不要使用引用返回!

	//加,这里不是使用引用返回是因为 d = d1+day 返回值应该是一个新创造的日期
	//如果使用引用返回,我们就会返回一个临时变量
	Date operator+(int day)
	{
		Date ret = *this;
		ret += day; //本质是 ret.operator+(day);
		return ret;
	}

-

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

2.7 自增自减运算符重载

d++

	//前置++,++d1,可以使用引用返回,减少拷贝
	Date& operator++()
	{
		*this += 1; //调用+=进行复用
		return *this;
	}

++d

	//后置++,d1++,后置++我们在函数参数中用一个int进行标识,这是c++的约定
	Date operator++(int)
	{
		//后置++我们返回的是加1之前的值
		//所以我们不能使用引用返回
		Date tmp = *this;//保留加之前的值
		*this += 1;
		return tmp;//返回加之前的值
	}

--d

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

d--

	//后置--,d1--
	Date operator--(int)
	{
		Date tmp = *this;//保留加之前的值
		*this -= 1;
		return tmp;//返回加之前的值
	}

至此一个完善的日期类就实现了,完整代码见Gitee


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

相关文章:

  • gitlab 服务器集群配置及 存储扩展配置
  • 正则表达式语法详解(python)
  • 技术理论||02空中三角测量
  • Java:从诞生到未来的编程语言进化史与应用前景
  • LeetCode --- 143周赛
  • 微服务即时通讯系统的实现(客户端)----(2)
  • 高效稳定!新加坡服务器托管方案助力企业全球化布局
  • centos7.9安装mysql社区版
  • 动态规划子数组系列一>乘积最大子数组
  • 介绍一下strcmp(c基础)
  • AI赋能社交平台:Facebook的智能化未来
  • 举例理解LSM-Tree,LSM-Tree和B+Tree的比较
  • 【jvm】方法区是否存在GC
  • 2024年中国金融大模型产业发展洞察报告(附完整PDF下载)
  • 【售前方案】工业园区整体解决方案,智慧园区方案,智慧城市方案,智慧各类信息化方案(ppt原件)
  • 3D Gaussian Splatting 代码层理解之Part2
  • Spring Boot 牛刀小试 org.springframework.boot:spring-boot-maven-plugin:找不到类错误
  • 手写模拟Spring Boot自动配置功能
  • Minikube 上安装 Argo Workflow
  • 【进阶编程】 分层结构和横纵向编程接口的结合
  • C/C++基础知识复习(23)
  • 【GameFramework框架】8-3、已经开发完成的虚拟仿真程序如何接入GameFramework框架
  • 3步实现贪吃蛇
  • [Docker#11] 容器编排 | .yml | up | 实验: 部署WordPress
  • Axure设计之文本编辑器制作教程
  • 字节青训-小C的外卖超时判断、小C的排列询问