【C++手撕系列】——设计日期类实现日期计算器

这篇具有很好参考价值的文章主要介绍了【C++手撕系列】——设计日期类实现日期计算器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【C++手撕系列】——设计日期类实现日期计算器,【C++手撕系列】,c++,开发语言,c语言

   
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!

😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
【C++手撕系列】——设计日期类实现日期计算器,【C++手撕系列】,c++,开发语言,c语言

前言🙌

    哈喽各位友友们😊,我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下! 都是精华内容,可不要错过哟!!!😍😍😍

    最近学习了C++的类和对象这部分的内容,然后自己手痒痒,就在空闲的时候手撕了一个日期类,按照网页版日期计算器有的功能进行一个一一的实现。纯粹分享,如果大家对日期计算器感兴趣的话也可以去实现一个自己的日期计算器,也可以借鉴我写的代码,有不懂的也可以来问我哦~废话不多说,咋们开始啦!!!

C嘎嘎类中六大护法实现代码:

在C嘎嘎中,有六大护法一直守护我们的类。分别是:

  • 构造函数
  • 析构函数
  • 拷贝构造函数
  • 赋值运算符重载函数
  • 取地址重载函数
  • const取地址重载函数

获取每一个月天数的函数源码分享

这里要注意的就是闰年和平年的2月天数的确定。闰年2月是29,平年是28天。

//获取每一个月的天数
int Date::GetMonthDay(int year, int month) const
{
	int DateArray[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 DateArray[month];
}

构造函数源码分享

这里需要注意的就是输入非法日期的情况,所以这里要给个检查,当输入非法日期就报错!!!

//构造函数
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 << "输入日期非法" << endl;
	}
}

拷贝构造函数源码分享

这里可以不用写拷贝构造,编译器可以默认生成。

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

析构函数源码分享

这里可以不用写析构,编译器可以默认生成。

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

赋值运算符重载函数源码分享

这里要避免 d1 = d1(自己给自己赋值)情况,所以加一个检查。其实也不用自己显示实现,编译器默认生成的赋值重载函数就可以了满足需求了~

//赋值运算符重载
Date& Date::operator=(const Date& d)
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

	return *this;
}

取地址和const取地址运算符重载函数源码分享

一般这两个函数不用写,编译器默认生成的就可以了。这里知识闲着无聊先出来看看而已。

//取地址和const取地址运算符重载
Date* Date:: operator&()
{
	return this;
}


const Date* Date:: operator&()const
{
	return this;
}

各种比较(> , >= ,< , <= , == , !=)运算符重载函数源码分享


//d1 < d2
bool Date::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;
	}
	else
	{
		return false;
	}
}

//d1 == d2
bool Date::operator==(const Date& d) const
{
	if (_year == d._year && _month == d._month
		&& _day == d._day)
	{
		return true;
	}
	return false;
}

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

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

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

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


各种运算的 运算符重载函数源码分享

这里写好了+= ,然后复用 += 实现 + ;同理,写好了 -= ,我们就可以复用 -= 来实现 - 。前置++和后置++,区别是后置++参数列表加一个int进行占位,用于区分前置和后置++;同理前置- -与后置- -也是这样规定实现的。



// d1 += d2
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;
}


Date Date::operator+(int day) const
{
	Date tem(*this);
	tem += day;
	return tem;
}


Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return (*this) += -(day);
	}
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			--_year;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}


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


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


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


流插入(cout)和流提取(cin)运算符重载函数源码分享


ostream& operator<< (ostream& out,const Date& d)
{
	out << d._year << "/" << d._month << "/" << d._day << endl;
	return out;
}


istream& operator>>(istream& in, Date& d)
{
	in >> d._year;
	in >> d._month;
	in >> d._day;
	return in;
}

日期 - 日期 函数源码分享

这个函数实现比较难想出来。这里先是确定出两个日期的大小关系,然后让小的日期不断++,n记录加的次数(也就是两个日期相隔的天数,当两个日期相等时,n*flag 就是结果。这里的flag是一个关键,当一开始是小日期 - 大日期时,flag 就是-1,计算出的答案自然是负数;当是大日期减小日期,flag就是1,答案自然就是正数。

int Date::operator-(const Date& d) const
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	int n = 0;
	while (min != max)
	{
		++min;
		++n;
	}
	return n * flag;
}

Date 日期类头文件源码:

#pragma once

#include<iostream>
using namespace std;

class Date
{
	// 友元声明
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);

public:
	int GetMonthDay(int year, int month) const;
	Date(int year = 1, int month = 1, int day = 1);
	//void Print() const;
	Date(const Date& d);
	~Date();
	// 只读函数可以加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) const;
	Date& operator-=(int day);
	Date operator-(int day) const;

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

	// 日常自动生成的就可以
	// 不想被取到有效地址
	Date* operator&();
	const Date* operator&() const;
private:
	int _year;
	int _month;
	int _day;
};

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


Date 日期类功能文件源码:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"

//获取每一个月的天数
int Date::GetMonthDay(int year, int month) const
{
	int DateArray[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 DateArray[month];
}

//构造函数
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 << "输入日期非法" << endl;
	}
}


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

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

//赋值运算符重载
//避免 d1 = d1(自己给自己赋值)情况
Date& Date::operator=(const Date& d)
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

	return *this;
}

//取地址和const取地址运算符重载
Date* Date:: operator&()
{
	return this;
}


const Date* Date:: operator&()const
{
	return this;
}


//d1 < d2
bool Date::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;
	}
	else
	{
		return false;
	}
}

//d1 == d2
bool Date::operator==(const Date& d) const
{
	if (_year == d._year && _month == d._month
		&& _day == d._day)
	{
		return true;
	}
	return false;
}

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

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

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

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

// d1 += d2
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;
}


Date Date::operator+(int day) const
{
	Date tem(*this);
	tem += day;
	return tem;
}


Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return (*this) += -(day);
	}
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			--_year;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}


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

ostream& operator<< (ostream& out,const Date& d)
{
	out << d._year << "/" << d._month << "/" << d._day << endl;
	return out;
}


istream& operator>>(istream& in, Date& d)
{
	in >> d._year;
	in >> d._month;
	in >> d._day;
	return in;
}

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


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

int Date::operator-(const Date& d) const
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	int n = 0;
	while (min != max)
	{
		++min;
		++n;
	}
	return n * flag;
}

Date 日期类测试文件源码:

#define _CRT_SECURE_NO_WARNINGS 
#include"Date.h"

//6大默认成员函数测试
void TestDate1()
{
	//构造测试
	Date d1;
	//拷贝构造测试
	Date d2(2023, 8, 11);
	//流插入运算符重载测试
	cout << d1;
	cout << d2;
	//流提取运算符重载测试
	cin >> d1;

	cout << d1;
	//取地址运算符重载测试
	cout << &d1 << endl;
	cout << &d2;

}


//测试日期大小比较以及计算日期往后或者往前几天的日期是多少
void TestDate2()
{
	Date d1(2003, 8, 23);
	Date d2(2023, 8, 11);
	/*cout << (d1 < d2) << endl;
	cout << (d1 <= d2) << endl;
	cout << (d1 > d2) << endl;
	cout << (d1 >= d2) << endl;
	cout << (d1 == d2) << endl;
	cout << (d1 != d2) << endl;*/


	//cout << d1;
	//d1 += 10000;
	//cout << d1;

	//d2 = d1 + 10000;
	//cout << d1;
	//cout << d2;

	//d1 += -1000;
	//cout << d1;
	//d1 = d2 + -1000;
	//cout << d1;

	/*d1 -= 11000;
	d2 = d1 - 1000;
	cout << d1;
	cout << d2;*/

}


void TestDate3()
{
	Date d1(2003, 8, 23);
	Date d2(2023, 8, 11);
	/*cout << d1;
	++d1;
	cout << d1;*/
	/*cout << d1;
	d2 = d1++;
	cout << d1;
	cout << d2;*/
	/*cout << d1;
	d2 = d1--;
	cout << d1;
	cout << d2;*/
	/*cout << d1;
	 d2 = ++d1;
	cout << d1;
	cout << d2;*/
	/*cout << d1;
	d2 = --d1;
	cout << d1;
	cout << d2;*/
}

void TestDate4()
{
	Date d1(2003, 8, 23);
	Date d2(2023, 8, 11);
	cout << (d2 - d1) << endl;
	cout << (d1 - d2) << endl;
}

int main()
{
	//TestDate1();
	//TestDate2();
	//TestDate3();
	TestDate4();


	return 0;
}

测试截图证明:

TestDate1函数的测试结果

【C++手撕系列】——设计日期类实现日期计算器,【C++手撕系列】,c++,开发语言,c语言

TestDate2函数的测试结果【C++手撕系列】——设计日期类实现日期计算器,【C++手撕系列】,c++,开发语言,c语言

TestDate3函数的测试结果

【C++手撕系列】——设计日期类实现日期计算器,【C++手撕系列】,c++,开发语言,c语言

TestDate4函数的测试结果

【C++手撕系列】——设计日期类实现日期计算器,【C++手撕系列】,c++,开发语言,c语言
与网页版日期计算器测试结果一致!!!!!
【C++手撕系列】——设计日期类实现日期计算器,【C++手撕系列】,c++,开发语言,c语言

小结语:

上述测试案例我只写了比较常规的,并没有做会更加仔细的测试。大家也可以帮我用链接: 网页版日期计算器测试一下我的程序有没有bug,我好及时更正!!!

总结撒花💞

   本篇文章旨在分享的是用C++ 设计日期类实现日期计算器的知识。希望大家通过阅读此文有所收获
   😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘文章来源地址https://www.toymoban.com/news/detail-642114.html

到了这里,关于【C++手撕系列】——设计日期类实现日期计算器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【c++】简单的日期计算器

    🔥个人主页 : Quitecoder 🔥 专栏 : c++笔记仓 朋友们大家好啊,在我们学习了默认成员函数后,我们本节内容来完成知识的实践,来实现一个简易的日期计算器 头文件声明所有函数: 第一个函数,获取 某月天数 为了按照月的月份直接访问数组,我们设置大小为13,由于要进

    2024年04月09日
    浏览(73)
  • 【C++】类与对象(日期计算器)

       🌈个人主页: 秦jh__https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343 🔥 系列专栏: 目录 头文件 函数实现      💬 hello! 各位铁子们大家好哇。              今日更新了类与对象日期计算器的内容      🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝 声明流插入和流提

    2024年03月10日
    浏览(61)
  • 【C++】如何用C++写一个日期计算器

    目录 前言 代码的布局 设计数据 方法声明 方法的实现 获取某年某月的天数 *全缺省的构造函数 * 拷贝构造函数 *赋值运算符重载 *析构函数 日期+=天数 日期+天数 日期-天数 日期-=天数 前置++ 后置++ 后置-- 前置-- 实现比较大小运算符重载思路 运算符重载 ==运算符重载 *  = 运算

    2024年04月23日
    浏览(54)
  • 【C++初阶】第三站:类和对象(中) -- 日期计算器

    目录 前言 日期类的声明.h 日期类的实现.cpp 获取某年某月的天数 全缺省的构造函数 拷贝构造函数 打印函数 日期 += 天数 日期 + 天数 日期 -= 天数 日期 - 天数 前置++ 后置 ++ 前置 -- 后置-- 日期类中比较运算符的重载 运算符重载 ==运算符重载 != 运算符重载 =运算符重载 运算符

    2024年02月19日
    浏览(44)
  • C++多态案例-设计计算器类

    多态是面向对象的三大特性之一 多态分为两类 静态多态: 函数重载 和 运算符重载 都属于静态多态,复用函数名 动态多态: 派生类 和 虚函数 实现运行时多态 静态多态和动态多态的区别 静态多态的函数地址早绑定-----编译阶段确定函数地址 动态多态的函数地址晚绑定--

    2024年02月10日
    浏览(44)
  • C++简易计算器的实现

    定义: 计算器是近代人发明的可以进行数字运算的机器。 也就是说,计算器不等同于算盘,前者能自行运算,后者只能简便计算过程,在古代,人们发明了许多计算工具,如算筹、算盘、计算尺等,随着社会的发展和科技的进步,计算工具也经历了由简单到复杂,由低级向高级的发

    2024年02月11日
    浏览(44)
  • verilog实现计算器设计

    该实验为用verilog编写的一个运算系统,其功能是实现4位整数的加、减、乘、除运算。运算时通过矩阵键盘输入运算类型和运算所需要的数据,然后通过内部电路处理,将计算的结果送于数码管或LCD1602显示。 工程截图如下: 本设计分为两个子模块,按键输入和数码管输出。

    2024年01月16日
    浏览(44)
  • 在线推算两个日期相差天数的计算器

     具体请前往:在线推算两个日期相差天数的计算器

    2024年02月14日
    浏览(51)
  • JAVA课程设计——GUI实现简易计算器

    一.设计任务及要求 任务:设计并实现一个计算器小程序 要求: 使用图形用户界面 能在键盘或鼠标上读入数据,并完成加,减,乘,除计算。 在屏幕上显示一个主菜单。 提示用户输入相应的数字键,分别执行加,减,乘,除计算功能和结束程序的功能。 二.需求分析: ​ 计算

    2024年02月12日
    浏览(44)
  • 布局设计和实现:计算器UI【TableLayout、GridLayout】

    根据自己的需求输入其他信息 填写完成后,点击 Finish 即可 在 res/layout 文件夹中的XML文件中创建UI界面。在这个XML文件中,您可以使用TableLayout来设计计算器界面。 2.1 创建layout文件夹 但是默认创建出来的项目并不会包含 layout 布局文件夹,因此需要我们自行创建 在 res 目录内

    2024年02月04日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包