C++ ——日期类的实现和注释浅解

news2024/9/21 17:18:03

目录

日期类实现

1. 日期+=天数

 2. 日期+天数

3. 日期-=天数 

 3.1 日期-天数 

4. 比较运算符

 5. 日期-日期

6. 代码汇总

Date.h

Date.cpp

Test.cpp


日期类实现

1. 日期+=天数

// d1 += 100
//+=可以改变d1,所以可以直接相加
Date& Date::operator+=(int day)
{
	//如果天数小于0
	if (day < 0)
	{
		return *this -= (-day);
	}
	//天数+天数
	_day += day;
	//当相加之后的天数大于当前月份的天数时进入循环
	while (_day > GetMonthDay(_year, _month))
	{
		//相加之后的天数减去当前月份的天数
		_day -= GetMonthDay(_year, _month);
		//月份++
		++_month;
		//当月份为13个月时
		if (_month == 13)
		{
			//年++,月为1
			_year++;
			_month = 1;
		}
	}

	return *this;
}

 2. 日期+天数

// d1 + 100
//+不能直接改变d1
Date Date::operator+(int day)
{
	//所以可以使用拷贝构造来拷贝一份D1的值赋给tmp
	Date tmp = *this;
	//方法1:直接调用+=
	tmp += day;
	//方法2:原理和+=相同,只不过是多了一个tmp
	/*tmp._day += day;
	while (tmp._day > GetMonthDay(tmp._year, tmp._month))
	{
		tmp._day -= GetMonthDay(tmp._year, tmp._month);
		++tmp._month;
		if (tmp._month == 13)
		{
			tmp._year++;
			tmp._month = 1;
		}
	}*/
	return tmp;
}


3. 日期-=天数 

//d1 -= 100 日期-=天数
Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return *this += (-day);
	}
	//天数-天数
	_day -= day;
	//当天数小于0时进入循环
	while (_day <= 0)
	{
		//借上一个月的天数
		--_month;
		//如果月份借完了,为0
		if (_month == 0)
		{
			//那么就借上一年的12月
			_month = 12;
			--_year;
		}
		//把上个月借来的天数加上
		_day += GetMonthDay(_year, _month);
	}

	return *this;
}

 3.1 日期-天数 

//d1 - 100 日期-天数
Date Date::operator-(int day) const
{
	//逻辑和+相同
	Date tmp = *this;
	tmp -= day;

	return tmp;
}


4. 比较运算符

两个日期的大小比较

当同时实现了小于+等于 或者 大于+等于就可以使用 赋用 来实现其他的比较运算符,不光适用于日期类,还适合所有的类的比较运算符

/*当同时实现了小于+等于 或者 大于+等于
就可以使用 复用 来实现其他的比较运算符*/

//d1的参数为this指针,d1的参数为d
bool Date::operator<(const Date& d)
{
	//如果年小于年
		if (_year < d._year)
		{
			return true;
		}//当年等于年时进入
		else if (_year == d._year)
		{
			//如果月小于月
			if (_month < d._month)
			{
				return true;
			}//当月等于月时进入
			else if (_month == d._month)
			{
				//比较天数大小
				return _day < d._day;
			}
		}
		//大于则返回false
		return false;
}

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


 5. 日期-日期

思路:先判断两个日期的大小,去小的那个日期,然后一直小的日期的++天数,直到小的日期与大的日期相等为止

//日期-日期
// d1 - d2
/*思路:先判断两个日期的大小,去小的那个日期,
然后一直小的日期的++天数,直到小的日期与大的日期相等为止*/
int Date::operator-(const Date& d) const
{
	//假设第一个大第二个小,flag = 1
	int flag = 1;
	//d1=this  d2=d
	Date max = *this;
	Date min = d;
	//如果第一个小第二个大,flag = -1
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	//定义一个n统计min和max中间相差多少天数
	int n = 0;
	//不相等进入循环
	while (min != max)
	{
		//前置++减少一点拷贝
		++min;
		//天数的差值
		++n;
	}
	//天数的差值*flag
	//当d1>d2,那么就为正数,d1<d2,则就为负数
	return n * flag;
}


6. 代码汇总

Date.h

#pragma once

#include<iostream>
using namespace std;
#include<assert.h>


//日期类只需要实现构造函数,其他的3个函数不需要实现


class Date
{
	//友元函数声明
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
	//检查日期
	bool CheckDate() const;
	Date(int year = 1900, int month = 1, int day = 1);
	//打印
	void Print() const;

	//打印
	//void Print();
	//默认是lnline
	//monthDayArray:用来获取莫一年莫一个月的天数
	int GetMonthDay(int year, int month)const 
	{
		//月份天数以数组下标为判断,第一个-1下标为0
		//把函数定义为静态,因为会频繁调用
		static int monthDayArray[13] = { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

		//判断是不是闰年,如果是闰年那么2月就是29天
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
		{
			return 29;
		}

		return monthDayArray[month];
	}

	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;

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

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

	// d1++;
	// d1.operator++(0);
	Date operator++(int);

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

	// d1--;
	// d1.operator--(0);
	Date operator--(int);

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

	// d1 - d2
	int operator-(const Date& d) const;

	//void operator<<(ostream& out);

	Date* operator&()
	{
		//return this;
		//return nullptr;
		return (Date*)0x2673FF40;
	}

	const Date* operator&() const
	{
		//return this;
		//return nullptr;
		return (Date*)0x2673FE30;
	}
private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);


Date.cpp

#include"Date.h"


//检查日期
bool Date::CheckDate() const
{
	if (_month < 1 || _month > 12
		|| _day < 1 || _day > GetMonthDay(_year, _month))
	{
		return false;
	}
	else
	{
		return true;
	}
}
Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;

	if (!CheckDate())
	{
		cout << "非法日期:";
		Print();
	}
}

// void Date::Print(const Date* const this)
void Date::Print() const
{
	//++_year;
	cout << _year << "/" << _month << "/" << _day << endl;
}



// d1 += 100
//+=可以改变d1,所以可以直接相加
Date& Date::operator+=(int day)
{
	//如果天数小于0
	if (day < 0)
	{
		return *this -= (-day);
	}
	//天数+天数
	_day += day;
	//当相加之后的天数大于当前月份的天数时进入循环
	while (_day > GetMonthDay(_year, _month))
	{
		//相加之后的天数减去当前月份的天数
		_day -= GetMonthDay(_year, _month);
		//月份++
		++_month;
		//当月份为13个月时
		if (_month == 13)
		{
			//年++,月为1
			_year++;
			_month = 1;
		}
	}

	return *this;
}

// d1 + 100
//+不能直接改变d1
Date Date::operator+(int day)
{
	//所以可以使用拷贝构造来拷贝一份D1的值赋给tmp
	Date tmp = *this;
	//方法1:直接调用+=
	tmp += day;
	//方法2:原理和+=相同,只不过是多了一个tmp
	/*tmp._day += day;
	while (tmp._day > GetMonthDay(tmp._year, tmp._month))
	{
		tmp._day -= GetMonthDay(tmp._year, tmp._month);
		++tmp._month;
		if (tmp._month == 13)
		{
			tmp._year++;
			tmp._month = 1;
		}
	}*/
	return tmp;
}

//d1 - 100 日期-天数
Date Date::operator-(int day) const
{
	//逻辑和+相同
	Date tmp = *this;
	tmp -= day;

	return tmp;
}



//d1 -= 100 日期-=天数
Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return *this += (-day);
	}
	//天数-天数
	_day -= day;
	//当天数小于0时进入循环
	while (_day <= 0)
	{
		//借上一个月的天数
		--_month;
		//如果月份借完了,为0
		if (_month == 0)
		{
			//那么就借上一年的12月
			_month = 12;
			--_year;
		}
		//把从上个月借来的天数加上
		_day += GetMonthDay(_year, _month);
	}

	return *this;
}



//比较运算符***********************
//两个日期比较大小
//d1的参数为this指针,d1的参数为d
bool Date::operator<(const Date& d)const
{
	//如果年小于年
		if (_year < d._year)
		{
			return true;
		}//当年等于年时进入
		else if (_year == d._year)
		{
			//如果月小于月
			if (_month < d._month)
			{
				return true;
			}//当月等于月时进入
			else if (_month == d._month)
			{
				//比较天数大小
				return _day < d._day;
			}
		}
		//大于则返回false
		return false;
}

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

/*当同时实现了小于+等于 或者 大于+等于
就可以使用 复用 来实现其他的比较运算符*/


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

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

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


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


//日期的前置++ 与 后置++
// d1++;
// d1.operator++(0);
Date Date::operator++(int)
{
	Date tmp = *this;
	*this += 1;
	return tmp;
}

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



//日期-日期
// d1 - d2
/*思路:先判断两个日期的大小,去小的那个日期,
然后一直小的日期的++天数,直到小的日期与大的日期相等为止*/
int Date::operator-(const Date& d) const
{
	//假设第一个大第二个小,flag = 1
	int flag = 1;
	//d1=this  d2=d
	Date max = *this;
	Date min = d;
	//如果第一个小第二个大,flag = -1
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	//定义一个n统计min和max中间相差多少天数
	int n = 0;
	//不相等进入循环
	while (min != max)
	{
		//前置++减少一点拷贝
		++min;
		//天数的差值
		++n;
	}
	//天数的差值*flag
	//当d1>d2,那么就为正数,d1<d2,则就为负数
	return n * flag;
}

//二元流插入
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}


//流插入
istream& operator>>(istream& in, Date& d)
{
	while (1)
	{
		cout << "请依次输入年月日:>";
		in >> d._year >> d._month >> d._day;

		if (!d.CheckDate())
		{
			cout << "输入日期非法:";
			d.Print();
			cout << "请重新输入!!!" << endl;
		}
		else
		{
			break;
		}
	}

	return in;
}


Test.cpp

#include"Date.h"

void TestDate1()
{
	Date d1(2024, 7, 12);
	Date d2 = d1 + 100;
	//Date d3(d1 + 100);
	d1.Print();
	d2.Print();

	//d1 += 100;
	//d1.Print();

	d1 += 30000;
	d1.Print();
}

void TestDate2()
{
	/*Date d1(2024, 7, 13);
	d1 -= 30000;
	d1.Print();*/

	Date d1(2024, 7, 13);
	Date ret1 = d1++;
	ret1.Print();
	d1.Print();

	Date d2(2024, 7, 13);
	Date ret2 = ++d2;
	ret2.Print();
	d2.Print();
}

void TestDate3()
{
	Date d1(2024, 7, 12);
	d1 += -100;
	d1.Print();

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

void TestDate4()
{
	Date d1(2034, 10, 1);
	Date d2(2024, 6, 31);

	cout << d1 - d2 << endl;
}

void TestDate5()
{
	Date d1, d2;
	cin >> d1 >> d2;
	cout << d1 << d2;

	cout << d1 - d2 << endl;

	//cout << d1;
	//operator<<(cout, d1);

	//cout << d1 << d2;

	// 倒反天罡
	//d1 << cout;
	//d1.operator<<(cout);
}

void TestDate6()
{
	const Date d1(2024, 7, 13);
	d1.Print();

	Date d2(2024, 7, 13);
	d2.Print();

	cout << &d1 << endl;
	cout << &d2 << endl;
}

//int main()
//{
//	TestDate6();
//
//	return 0;
//}

#include<iostream>
using namespace std;
class A
{
public:
	//explicit A(int a = 0)
	A(int a = 0)
	{
		_a1 = a;
	}

	A(const A& aa)
	{
		_a1 = aa._a1;
	}

	A(int a1, int a2)
		:_a1(a1)
		, _a2(a2)
	{}

	void Print() {
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a1;
	int _a2;
};

class Stack
{
public:
	void Push(const A& aa)
	{
		//...
	}
private:
	A _arr[10];
	int _top;
};

int main()
{
	A aa1(1);
	aa1.Print();

	// 隐式类型转换
	// 2构造一个A的临时对象,再用这个临时对象拷贝构造aa2
	// 编译器遇到连续构造+拷贝构造->优化为直接构造
	A aa2 = 2;
	aa2.Print();

	A& raa1 = aa2;
	const A& raa2 = 2;

	int i = 1;
	double d = i;
	const double& rd = i;

	Stack st;

	A aa3(3);
	st.Push(aa3);

	st.Push(3);

	// C++11
	A aa5 = { 1, 1 };
	const A& raa6 = { 2,2 };
	st.Push(aa5);
	st.Push({ 2,2 });

	return 0;
}


感谢观看~ 

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

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

相关文章

2024年中国研究生数学建模竞赛F题思路代码模型文章——X射线脉冲星光子到达时间建模

2024年中国研究生数学建模竞赛F题 X射线脉冲星光子到达时间建模 脉冲星&#xff08;Pulsar&#xff09;是高速自转的中子星&#xff0c;具有体积小、密度大的特征。脉冲星的高速自转会形成脉冲&#xff0c;而脉冲的周期其实就是脉冲星的自转周期 。在旋转过程中&#xff0c;脉…

2024年华为杯研赛(B题)数学建模竞赛解题思路|完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

CleanClip --- 为Mac用户打造的智能剪贴板管理利器

CleanClip是一款专为Mac用户设计的强大剪贴板管理工具&#xff0c;旨在提升用户的工作效率和数据管理体验。它通过智能化的剪贴板内容管理&#xff0c;实现了Mac系统与用户操作之间的无缝衔接。CleanClip支持多种连接方式&#xff0c;包括系统级的快捷操作和自定义快捷键&#…

虚拟机VMware安装+centos8

1、安装虚拟机 这里以VMware-workstation-full-14.1.1-7528167.exe为例进行安装虚拟机。 注意win11&#xff0c;不能安装14的版本&#xff0c;新建虚拟机打开会崩的。建议换成16版本的。 此处安装的为centos7版本&#xff0c;双击就可以开始安装了。 选择下一步 勾选我接受&a…

Node.js官网无法正常访问时安装NodeJS的方法

目录 一、使用 nvm 进行安装二、通过阿里云开源镜像站进行安装 一、使用 nvm 进行安装 此时如果直接使用 nvm install 命令进行安装会报错&#xff1a; nvm install 16.14.0Could not retrieve https://nodejs.org/dist/latest/SHASUMS256.txt. Get “https://nodejs.org/dis…

docker基本(仅供自己参考)

一、大型项目部署的问题&#xff1a; 1、大型项目的组件比较多&#xff0c;运行环境很复杂&#xff0c;部署通常会遇到各种问题&#xff1a; &#xff08;1&#xff09;&#xff1a;依赖关系复杂&#xff0c;容易出现兼容性问题 &#xff08;2&#xff09;&#xff1a;开发、…

ORCDA仿真功能_PS_PISC,显示窗口小,模板工程,光标,查看值

1 开启PS_PICE仿真功能 1 新建 2 可以选择已有模板工程 3 创建模板工程 2 进行仿真 1 设置仿真时间 2 可以用光标测量不同曲线位置的信息&#xff08;如电压&#xff09; 1 光标&#xff0c;可以测量不同点的电压 2 Trace&#xff08;测量功率&#xff09;&#xff0c;加…

基于SpringBoot+Vue的剧本杀管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

计算机网络:物理层 --- 基本概念、编码与调制

目录 一. 物理层的基本概念 二. 数据通信系统的模型 三. 编码 3.1 基本概念 3.2 不归零制编码 3.3 归零制编码 3.4 曼切斯特编码 3.5 差分曼切斯特编码 ​编辑 四. 调制 4.1 调幅 4.2 调频 4.3 调相 4.4 混合调制 今天我们讲的是物理…

gitlab/极狐-离线包下载地址

如果想要使用Gitlab/极狐进行数据的恢复&#xff0c;只能使用相同版本或者相近版本的安装包&#xff0c;因此有时候需要到它的官网上下载对应版本的安装包&#xff0c;以下是我收集到的对应地址的下载路径&#xff1a; Gitlab Gitlab离线库&#xff0c; https://packages.gitl…

Prometheus架构详解

1 Prometheus简介 Prometheus 是一个开源的系统监控报警工具套件&#xff0c;它最初由SoundCloud开发&#xff0c;并于2016年成为CNCF&#xff08;云原生计算基金会&#xff09;托管的第二个项目&#xff08;第一个是kubernetes&#xff09;。Prometheus 以其简单高效的方式收…

MySQL练手题--日期连续类型(困难)

一、准备工作 Create table If Not Exists Failed (fail_date date); Create table If Not Exists Succeeded (success_date date); Truncate table Failed; insert into Failed (fail_date) values (2018-12-28); insert into Failed (fail_date) values (2018-12-29); inser…

【复现】Grounding DINO使用记录

推理 问题 1. ModuleNotFoundError: No module named groundingdino 解决&#xff1a; 运行 python setup.py install 编译groundingdino库。或者直接引入环境变量&#xff1a; linux&#xff1a; export PYTHONPATH$PYTHONPATH:/data/groundingdino windows&#xff1…

力扣最热一百题——除自身以外数组的乘积

目录 题目链接&#xff1a;238. 除自身以外数组的乘积 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示&#xff1a; 解法一&#xff1a;左右数组&#xff08;小型动态规划&#xff09; 实现思路 Java写法&#xff1a; 运行时间 C写法&#xff1a; 运行时…

Acwing Hash表

哈希表的作用&#xff1a;把一个比较大的空间&#xff0c;通过一个函数映射到一个比较小的空间 一般做哈希运算时&#xff0c;取一个质数作为模&#xff0c;会使得冲突的概率降低。 哈希表的冲突解决方法&#xff1a; 拉链法开放寻址法 下面详细介绍这两种方法的原理及其实现…

Java+Spring Cloud +UniApp 智慧工地源码,用户PC端、移动端数据同步,支持多端展示

数字化给各行各业所带来的改变&#xff0c;在早些年间突出自动这一流程。但随着科技的发展&#xff0c;让人们也愈发了解可视化操作所带来的优势。智慧工地的诞生&#xff0c;相当于为建筑施工带来了一套较为完整的数字化流程&#xff0c;能够完善施工环节中的各部分内容。接下…

C++【类和对象】(一)

文章目录 前言1.类的定义1.1类定义格式1.2 访问限定符1.3 类域 2. 实例化2.1 实例化的概念2.2 对象大小 3.this指针结语 前言 在前文我们讲解了C基础语法知识。本文将会讲解C的类和对象。 1.类的定义 1.1类定义格式 class name {}&#xff1b;class为定义类的关键字&#x…

8586 括号匹配检验

### 思路 1. **初始化栈**&#xff1a;创建一个空栈用于存储左括号。 2. **遍历字符串**&#xff1a;逐个字符检查&#xff1a; - 如果是左括号&#xff08;( 或 [&#xff09;&#xff0c;则入栈。 - 如果是右括号&#xff08;) 或 ]&#xff09;&#xff0c;则检查栈是…

【医学半监督】对比互补掩蔽的自监督预训练半监督心脏图像分割

SELF-SUPERVISED PRE-TRAINING BASED ON CONTRASTIVE COMPLEMENTARY MASKING FOR SEMI-SUPERVISED CARDIAC IMAGE SEGMENTATION 2024 IEEE International Symposium on Biomedical Imaging (ISBI) 摘要: 心脏结构分割对心脏病诊断非常重要,而使用大量注释的深度学习在这项任…

记录|C#的资源路径设置的资料整理

目录 前言一、在这里插入图片描述 https://bbs.csdn.net/topics/360001606 二、三、添加到资源文件中四、获得图片的三种路径方法五、给资源文件添加文件夹更新时间 前言 参考文章&#xff1a; 原本以为C# winform中进行图片等文件的路径的读取是直接可以按照资源文件中显示的来…