日期类的实现【C++】

news2024/10/8 12:15:37

1、Date.h

#pragma once
#include <iostream>
using namespace std;

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1);

	void Print();

	//Date& operator=(const Date& d); //赋值重载

	int GetMonthDay(int year, int month);


	bool operator<(const Date& d); //d1 就是 this,d2 就是 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);


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


	//++d1 -> d1.operator++()
	Date& operator++();

	//d1++ -> d1.operator++(0)
	//【加一个int参数,进行占位,跟前置++构成函数重载进行区分】
	//【本质:后置++调用,编译器进行特殊处理】
	Date operator++(int i);

	Date& operator--();
	Date operator--(int i);

private:
	//内置类型
	int _year;
	int _month;
	int _day;
};

2、Date.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "Date.h"

Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;

	//检查日期是否合法
	if (month < 1 || month>12 || day<1 || day>GetMonthDay(year, month))
	{
		cout << "非法日期:";
		//exit(-1);
	}
}

void Date::Print()
{
	cout << _year << "年" << _month << "月" << _day << "日" << endl;
}

int Date::GetMonthDay(int year, int month)
{
	//GetMonthDay会被重复调用,加一个static就不用每次调用都创建一个数组,节省了空间
	static int monthArray[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 monthArray[month];
}

bool Date::operator<(const Date& d) //d1 就是 this,d2 就是 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;
	}
}

//d1==d1
bool Date::operator==(const Date& d) //d1 就是 this,d2 就是 d
{
	return (_year == d._year && _month == d._month && _day == d._day);
}

//d1<=d2
bool Date::operator<=(const Date& d) //d1 就是 this,d2 就是 d
{
	return *this < d || *this == d; //*this就是d1,d就是d2
}

//d1>d2
bool Date::operator>(const Date& d)
{
	return !(*this <= d); //>就是<=取反
}

//d1>=d2
bool Date::operator>=(const Date& d)
{
	return !(*this < d); //>=就是<取反
}

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

Date& Date::operator+=(int day) //日期+天数
{
	//若+=负数,等于-=正数
	if (day < 0)
	{
		return *this -= (-day);
	}

	_day += day;

	while (_day > GetMonthDay(_year, _month))
	{
		//月进位
		_day -= GetMonthDay(_year, _month);
		++_month;

		//月满,年进位
		if (_month == 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this; //this是指针,返回*this
}

Date Date::operator+(int day)
{
	Date tmp(*this);
	tmp += day;
	return tmp;

	//tmp._day += day;
	//while (tmp._day > GetMonthDay(tmp._year, tmp._month))
	//{
	//	//月进位
	//	tmp._day -= GetMonthDay(tmp._year, tmp._month);
	//	++_month;

	//	//月满,年进位
	//	if (tmp._month == 13)
	//	{
	//		++tmp._year;
	//		tmp._month = 1;
	//	}
	//}
	//return tmp;
}

//Date& Date::operator=(const Date& d)
//{
//	if (this != &d) //屏蔽d1=d1的操作
//	{
//		this->_year = d._year;
//		this->_month = d._month;
//		this->_day = d._day;
//	}
//	return *this;
//}

Date& Date::operator-=(int day)
{
	//若-=负数,等于+=正数
	if (day < 0)
	{
		return *this += (-day);
	}

	_day -= day;

	while (_day < 1)
	{
		_month--;
		if (_month == 0)
		{
			_year--;
			_month = 12;
		}

		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

Date Date::operator-(int day)
{
	Date tmp(*this);
	tmp -= day;
	return tmp;
}

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

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

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

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

int Date::operator-(const Date& d)
{
	Date max = *this;
	Date min = d;
	int flag = 1;

	if (max < min)
	{
		max = d;
		min = *this;
		flag = -1;
	}

	int n = 0;
	while (min != max) //算相差的天数
	{
		++min;
		++n;
	}

	return n * flag;
}

在这里插入图片描述


3、Test.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "Date.h"

void Test1()
{
	Date d1(2023, 7, 23);
	d1.Print();

	Date d2(2023, 8, 23);
	d2.Print();

	Date d3(2023, 13, 0);
	d3.Print();
}

void Test2()
{
	Date d1(2023, 7, 23);
	d1.Print();

	Date d2(2023, 8, 13);
	d2.Print();

	//拷贝构造,一个已经存在的对象去初始化另外一个要创建的对象
	Date d3(d2); //默认拷贝构造
	d3.Print();

	//赋值,两个已经存在的对象进行拷贝
	d1 = d2; //d1.operator=(d2);
	d1.Print();

	d1 = d2 = d3;
	d1.Print();
}

void Test3()
{
	Date d1(2023, 7, 27);
	d1 += 2000;
	d1.Print();

	Date d2(2023, 7, 27);

	Date ret = d2; //拷贝构造,不是赋值 
	/*Date ret;
	ret = d2 + 2000;*/ //这是赋值
	ret.Print();
}

void Test4()
{
	Date d1(2023, 7, 27);
	d1 -= 2000;
	d1.Print();

	d1 -= -200;
	d1.Print();
}

void Test5()
{
	Date d1(2023, 7, 27);
	Date ret1 = d1++;
	//Date ret1 = d1.operator++(0); //显式调用,此处的值传多少都无所谓
	ret1.Print();
	d1.Print();

	Date ret2 = ++d1;
	//Date ret2 = d1.operator++(); //显式调用
	ret2.Print();
	d1.Print();
}

void Test6()
{
	Date d1(2002, 12, 14);
	Date d2(2023, 7, 27);
	cout << d2 - d1 << endl;
}

int main()
{
	cout << "Test1:" << endl;
	Test1();

	cout << endl;

	cout << "Test2:" << endl;
	Test2();

	cout << endl;

	cout << "Test3:" << endl;
	Test3();

	cout << endl;

	cout << "Test4:" << endl;
	Test4();

	cout << endl;

	cout << "Test5:" << endl;
	Test5();

	cout << endl;

	cout << "Test6:" << endl;
	Test6();

	return 0;
}

4、运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/803071.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSDN周赛66期图文题解 - 路灯亮度 池塘水量

本期非编程题考察更多是对原书的阅读理解&#xff0c;可能还是因为自己理解不够&#xff0c;翻了半天书&#xff0c;还是错了两道。失之我命&#xff0c;不多废话。 本期编程题比较符合我的胃口&#xff0c;有陷阱&#xff0c;有技巧&#xff0c;窃以为是最近不少期里比较有意…

华为eNSP通过VMnet8虚拟网卡,NAT转换访问互联网

防火墙上配置&#xff1a; 配置G1/0/1接口IP地址&#xff0c;其实G1/0/1的IP就是终端PC1的网关地址。 配置G1/0/0接口自动获取IP地址&#xff0c;从VMnet8中自动获取地址。 配置安全区域zone,把对应的接口加入到对应的zone中 配置安全策略&#xff0c;放通trust安全区域到u…

基于Vue3+LeaderLine实现画线时对应点放大精确选点功能

我们在画线时&#xff0c;可能开始结束位置选择不准&#xff0c;导致测量结果会有偏差&#xff0c;所以新增放大功能&#xff0c;如下所示 核心源码&#xff1a; <template>...<el-col :span"2" v-if"largeImageSelected"><!-- 显示在右…

Redis简介,设置redis内存大小,设置redis淘汰机制,查看内存占用情况,内存占用分析

为什么使用Redis缓存数据库 我们日常的开发&#xff0c;无非是对数据的处理。程序的定义也可以这样狭义的解释&#xff1a;算法数据。可见数据库是多么重要的工具。但是关系型数据库的读写能力在200-1000次/秒不等&#xff0c;服务器好点可能更多&#xff0c;这导致在高并发的…

w10修改cmd用户中文名

注销当前使用的账户&#xff0c;使用Administrator登录。右击左下角的开始&#xff0c;找到注销 一般注销之后&#xff0c;是没有Administrator登录的&#xff0c;因为Windows自动将它禁用了&#xff0c;所以在注销之前&#xff0c;你应该先右击我的电脑&#xff0c;点击管理&a…

学习笔记十三:云服务器通过Kubeadm安装k8s1.25,供后续试验用

Kubeadm安装k8s1.25 k8s环境规划&#xff1a;初始化安装k8s集群的实验环境先建生产环境服务器&#xff0c;后面可以通过生成镜像克隆node环境修改主机名配置yum源关闭防火墙关闭selinux配置时间同步配置主机 hosts 文件&#xff0c;相互之间通过主机名互相访问 **192.168.40.18…

argo workflows archived 归档设置

由于工作需要配置argo workflows归档&#xff0c;介绍一下大致步骤: 文章目录 1.在k8s中是找这个configmap2.编辑configmap3 配置数据库用户名和密码&#xff1a;4.把workflow这个pod删掉&#xff0c;让他重新生成一个 1.在k8s中是找这个configmap kubectl get cm -n argo2.编…

SpringBoot集成Lock4j 底层使用Redission 实现分布锁

Lock4j 在分布式系统中&#xff0c;实现锁的功能对于保证数据一致性和避免并发冲突是非常重要的。Lock4j是一个简单易用的分布式锁框架&#xff0c;而Redisson是一个功能强大的分布式解决方案&#xff0c;可以与Lock4j进行集成。 操作步骤 第一步&#xff1a;添加依赖 首先&…

uniAPP 视频图片预览组件

效果图 思路&#xff1a;处理文件列表&#xff0c;根据文件类型归类 已兼容 H5 ios 设备&#xff0c;测试已通过 浙政钉&#xff0c;微信小程序 视频资源因为&#xff0c;没有预览图&#xff0c;用灰色图层加播放按钮代替 <template><!--视频图片预览组件 -->&l…

【2023最新教程】6个步骤从0到1开发自动化测试框架(0基础也能看懂)

一、序言 随着项目版本的快速迭代、APP测试有以下几个特点&#xff1a; 首先&#xff0c;功能点多且细&#xff0c;测试工作量大&#xff0c;容易遗漏&#xff1b;其次&#xff0c;代码模块常改动&#xff0c;回归测试很频繁&#xff0c;测试重复低效&#xff1b;最后&#x…

使用MyBatis(1)

目录 一、什么是MyBatis 二、搭建MyBatis开发环境 &#x1f345;添加MyBatis依赖 &#x1f345;在数据库添加数据 &#x1f345;设置MyBatis配置 &#x1f388;数据库的相关连接信息&#x1f388;xml的保存和设置路径 三、使用MyBatis模式和语法操作数据库 &#x1f34…

BGP的介绍

目录 BGP基础 BGP的发展历史 BGP在企业中的应用 距离矢量型协议和路径矢量型协议的区别 BGP的特征 1.可控性 2.可靠性 3.AS-BY-AS BGP的对等关系 BGP的数据包 1.open报文 2.Keepalive报文 3.Update报文 4.Notification 报文 5.Route-refresh报文 BGP的状态机 …

GitLab备份升级

数据备份(默认的备份目录在/var/opt/gitlab/backups/下&#xff0c;生成一个以时间节点命名的tar包。) gitlab-rake gitlab:backup:create新建repo源&#xff0c;升级新版本的gitlab vim /etc/yum.repos.d/gitlab-ce.repo [gitlab-ce] namegitlab-ce baseurlhttps://mirrors.…

EMQ X 集群部署

EMQ X 消息服务器集群基于 Erlang/OTP 分布式设计,集群原理可简述为下述两条规则: MQTT 客户端订阅主题时,所在节点订阅成功后广播通知其他节点:某个主题(Topic)被本节点订阅。 MQTT 客户端发布消息时,所在节点会根据消息主题(Topic),检索订阅并路由消息到相关节点。 1. 集…

ICLR 2023 | 用于分布外泛化的拓扑感知鲁棒优化

论文链接&#xff1a;https://openreview.net/pdf?idylMq8MBnAp 代码链接&#xff1a;GitHub - joffery/TRO: The Pytorch implementation for "Topology-aware Robust Optimization for Out-of-Distribution Generalization" (ICLR 2023) 01. 研究背景 近年来&…

虹科分享 | 工业4.0:IO-Link wireless等先进通信技术是不可或缺的支柱

近年来&#xff0c;随着工业4.0&#xff08;工业革命4.0&#xff09;的提出&#xff0c;制造业转型浪潮拉开帷幕。工业4.0是将数字技术整合到传统的制造流程中&#xff0c;从而创建智能工厂。对此类工厂的最初要求是工厂各个层面的完全连接&#xff0c;从制造车间一直到管理和云…

重大更新|Sui主网即将上线流动性质押,助力资产再流通

Sui社区一直提议官方上线流动质押功能&#xff0c;现在通过SIP过程&#xff0c;已经升级该协议以实现这一功能。 Sui使用委托权益证明机制&#xff08;DPoS&#xff09;来选择和奖励负责运营网络的验证节点。为了保障网络安全&#xff0c;验证节点通过质押SUI token获得质押奖…

win10小任务栏显示日期

win10存在一个问题, 就是任务栏为小任务栏时, 无法显示系统日期, 只能显示时间, 对这个问题有两个办法, 1, 把小任务栏改为大任务栏, 日期就能显示出来 但如果你就是想用小任务栏, 不想用大任务栏, 又想显示日期, 只靠win10内置的设置是没法实现的, 只能借助其他软件, 具体看…

HTTP协议揭秘:探寻互联网的背后密码、探秘数据传输的奥秘

HTTP&#xff08;超文本传输协议&#xff1a;Hypertext Transfer Protocol&#xff09;是一种用于在Web上传输数据的协议&#xff0c;它是互联网上最重要的应用层协议之一。从诞生至今&#xff0c;HTTP一直扮演着连接世界的通信桥梁的角色&#xff0c;在互联网的发展和普及中发…

数组练习题,数组的动态初始化

数组的遍历 定义一个数组&#xff0c;求和 int[] arr {1,2,3,4,5,6,7};int sum 0;for (int i 0; i <arr.length ; i) {sum sum arr[i];}System.out.println(sum);定义一个数组&#xff0c;统计数组里面一共有多少能够被3 整除的数字&#xff1a; int[] arr1 {4,62,8…