【C++基础】实现日期类

在这里插入图片描述

​👻内容专栏: C/C++编程
🐨本文概括: C++实现日期类。
🐼本文作者: 阿四啊
🐸发布时间:2023.9.7

对于类的成员函数的声明和定义,我们在类和对象上讲到过,需要进行声明和定义分离。

一些需要使用的接口函数声明,我们放入到Date.h文件中
#include <iostream>
using namespace std;class Date
{public://构造函数Date(int year = 1, int month = 1, int day = 1);//拷贝构造函数Date(const Date& d);//析构函数//~Date(); //日期类可以不写//打印日期void Print()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=(const Date& d);//日期+= 天数Date& operator+=(int day);//日期 + 天数Date operator+(int day) const;//日期 -= 天数Date& operator-=(int day);//日期 - 天数Date operator-(int day) const;//获取当月天数int GetMonthDay(int year, int month) const;//前置++Date& operator++();//后置++Date operator++(int);//前置--Date& operator--();//后置--Date operator--(int);//日期 - 日期 返回天数int operator-(const Date& d) const;private:int _year;int _month;int _day;
};

🤗🤗下面,我们对一些日期接口函数的实现:

实现于Date.cpp文件中

一、构造函数、拷贝构造以及日期的打印

#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 << "非法日期" << endl;//exit(-1);}
}
Date::Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}
//Date::~Date()
//{
//	cout << "~Date()" << endl;
//}
void Date::Print() const
{cout << _year << "年" << _month << "月" << _day << "日" << endl;
}

二、赋值运算符重载函数

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

三、运算符重载

比较运算符重载

我们写一个operator< 运算符重载函数和一个 operator== 运算符重载函数即可,其他直接复用就行。

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;}
}
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) || (*this == d);
}
bool Date::operator!=(const Date& d) const
{return !(*this == d);
}

日期 ± 天数、日期 - 日期

获取当前月份的天数

首先我们需要写一个获取当月的天数GetMonthDay()函数,以便于后面用日期 ± 天数运算。

//获取当月天数
int Date::GetMonthDay(int year, int month) const
{static int MonthDayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//判断是否为闰年(先判断是否为2月)if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 4 == 0))){return 29;}return MonthDayArray[month];
}

日期 += 天数 与 日期 + 天数

//日期+= 天数
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 tmp(*this);tmp += day;return tmp;
}
日期+ 天数
//Date Date::operator+(int day)
//{
//	Date tmp(*this);
//	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;
//}
//
日期 += 天数
//Date& Date::operator+=(int day)
//{
//	*this = *this + day;
//	return *this;
//}

在这里插入图片描述

日期 -= 天数 与 日期 - 天数

我们知道了先写operator+=,再写operator+直接复用即可这种方法更优,所以我们日期减去天数也是实现operator-=,再实现operator-

//日期 -= 天数
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 tmp(*this);tmp -= day;return tmp;
}

自增 和 自减 重载

C++规定:前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载,后置++重载时多增加了一个int类型的参数,与前置++构成函数重载,以区分前置++

//前置++
Date& Date::operator++()
{*this += 1;//返回++之后的值return *this;
}
//后置++
Date Date::operator++(int)
{Date tmp(*this);//返回++之前的值*this += 1;return tmp;
}//前置--
Date& Date::operator--()
{*this -= 1;return *this;
}
//后置--
Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}

日期 - 日期

// d1 - d2
int Date::operator-(const Date& d) const
{//默认认为左边日期大Date max = *this;Date min = d;int flag = 1;//为1返回正数,-1返回负数int count = 0;//统计天数//不成立则交换if (*this < d){max = d;min = *this;flag = -1;}//while(min < max)while (min != max){min++;count++;}return count * flag;
}

四、全局函数实现流插入流提取

date.h 流插入流提取重载函数的声明
/*不能重载成成员函数,否则会导致参数不匹配,因为this指针永远占据第一个位置,无法进行流插入提取操作。*/
//流插入
ostream& operator<<(ostream& out, const Date& d);
//流提取
istream& operator>>(istream& in, Date& d);

如果重载成成员函数,那么成员函数的第一个参数永远是隐藏的this指针,成员函数中只能利用out << _year << _month << _day的顺序,但是在调用时, (d1为日期类对象)d1 << cout,只能这么写,虽然可以,但是很别扭,不符合使用习惯和价值。所以我们需要实现成全局函数才可以。
在这里插入图片描述
但是写成全局函数会访问类的成员变量,我们可以利用友元或者将成员变量封装成成员函数解决。

date.cpp 流插入流提取重载函数的实现
/*不能重载成成员函数,否则会导致参数匹配,因为this指针永远占据第一个位置,无法进行流插入提取操作。*/
//涉及访问私有成员变量可以利用友元,或者将成员变量封装成Get成员函数
//流插入
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 >> d._month >> d._day;
}

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

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

相关文章

c++通过tensorRT调用模型进行推理

模型来源&#xff1a; 算法工程师训练得到的onnx模型 c对模型的转换&#xff1a; 拿到onnx模型后&#xff0c;通过tensorRT将onnx模型转换为对应的engine模型&#xff0c;注意&#xff1a;训练用的tensorRT版本和c调用的tensorRT版本必须一致。 如何转换&#xff1a; 算法工…

2020年12月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:数组指定部分逆序重放 将一个数组中的前k项按逆序重新存放。例如,将数组8,6,5,4,1前3项逆序重放得到5,6,8,4,1。 时间限制:1000 内存限制:65536 输入 输入为两行: 第一行两个整数,以空格分隔,分别为数组元素的个数n(1 < n…

在Qt5中SQLite3的使用

一、SQLite简要介绍 什么是SQLite SQLite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其他数据库不一样&#xff0c;您不需要在系统中配置。 就像其他数据库&#xff0c;S…

基于javaweb的CT图像管理系统(servlet+jsp)

系统简介 本项目采用eclipse工具开发&#xff0c;jspservletjquery技术编写&#xff0c;数据库采用的是mysql&#xff0c;navicat开发工具。 三个角色&#xff1a;管理员&#xff0c;普通用户&#xff0c;医生 模块简介 管理员&#xff1a; 1、登录 2、用户管理 3、医生管…

ARM DIY(十)LRADC 按键

前言 ARM SOC 有别于单片机 MCU 的一点就是&#xff0c;ARM SOC 的 GPIO 比较少&#xff0c;基本上引脚都有专用的功能&#xff0c;因为它很少去接矩阵键盘、众多继电器、众多 LED。 但有时 ARM SOC 又需要三五个按键&#xff0c;这时候 LRADC 就是一个不错的选择&#xff0c;…

C# OpenVino Yolov8 Detect 目标检测

效果 项目 代码 using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using static System.Net.Mime.MediaT…

python趣味编程-数独游戏

数独游戏是一个用Python编程语言编写的应用程序。该项目包含可以显示实际应用程序的基本功能。该项目可以让修读 IT 相关课程并希望开发简单应用程序的学生受益。这个Python 数独游戏是一个简单的项目,可用于学习tkinter库的实践。这个数独游戏可以提供Python编程的基本编码技…

黑马JVM总结(三)

&#xff08;1&#xff09;栈内存溢出 方法的递归调用&#xff0c;没有设置正确的结束条件&#xff0c;栈会有用完的一天&#xff0c;导致栈内存溢出 可以修改栈的大小&#xff1a; 再次运行&#xff1a;减少了次数 案例二&#xff1a; 两个类的循环应用问题&#xff0c;导致Js…

linux-进程-execl族函数

exec函数的作用&#xff1a; 我们用fork函数创建新进程后&#xff0c;经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时&#xff0c;该进程被完全替换为新程序。因为调用exec函数并不创建新进程&#xff0c;所以前后进程的ID并没有改变。 简单来说就是&…

如何使用聊天GPT自定义说明

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 OpenAI ChatGPT正在席卷全球。一周又一周&#xff0c;更新不断提高您可以使用这种最先进的语言模型做什么的标准。 在这里&#xff0c;我们深入研究了OpenAI最近在ChatGPT自定义指令上发布的公告。此功能最初以测试版…

第11篇:ESP32vscode_platformio_idf框架helloworld点亮LED

第1篇:Arduino与ESP32开发板的安装方法 第2篇:ESP32 helloword第一个程序示范点亮板载LED 第3篇:vscode搭建esp32 arduino开发环境 第4篇:vscodeplatformio搭建esp32 arduino开发环境 ​​​​​​第5篇:doit_esp32_devkit_v1使用pmw呼吸灯实验 第6篇:ESP32连接无源喇叭播…

智慧公厕是对智慧城市“神经末梢”的有效激活,公共厕所实现可感知、可视化、可管理、可控制

在当今科技迅速发展的时代&#xff0c;智慧城市已经成为人们关注的热点话题。作为城市基础设施的重要组成部分&#xff0c;公共厕所也逐渐融入到智慧城市的建设中&#xff0c;成为城市管理的焦点之一。智慧公厕作为智慧城市的“神经末梢”&#xff0c;通过可感知、可视化、可管…

【文末送书】Matlab科学计算

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

遥感图像应用:在低分辨率图像上实现洪水损害检测(迁移学习)

本文是上一篇关于“在低分辨率图像上实现洪水损害检测”的博客的延申。 代码来源&#xff1a;https://github.com/weining20000/Flooding-Damage-Detection-from-Post-Hurricane-Satellite-Imagery-Based-on-CNN/tree/master 数据储存地址&#xff1a;https://github.com/Jef…

CSS宽度问题

一、魔法 为 DOM 设置宽度有哪些方式呢&#xff1f;最常用的是配置width属性&#xff0c;width属性在配置时&#xff0c;也有多种方式&#xff1a; widthmin-widthmax-width 通常当配置了 width 时&#xff0c;不会再配置min-width max-width&#xff0c;如果将这三者混合使…

MySql 变量

1.系统变量 1.1 系统变量分类 变量由系统定义&#xff0c;不是用户定义&#xff0c;属于 服务器 层面。系统变量分为全局系统变量&#xff08;需要添加 global 关键字&#xff09;以及会话系统变量&#xff08;需要添加 session 关键字&#xff09;&#xff0c;有时也把全局系…

Web安全——Web安全漏洞与利用上篇(仅供学习)

SQL注入 一、SQL 注入漏洞1、与 mysql 注入的相关知识2、SQL 注入原理3、判断是否存在注入回显是指页面有数据信息返回id 1 and 114、三种 sql 注释符5、注入流程6、SQL 注入分类7、接受请求类型区分8、注入数据类型的区分9、SQL 注入常规利用思路&#xff1a;10、手工注入常规…

MySQL的权限管理与远程访问

MySQL的权限管理 1、授予权限 授权命令&#xff1a; grant 权限1,权限2,…权限n on 数据库名称.表名称 to 用户名用户地址 identified by ‘连接口令’; 该权限如果发现没有该用户&#xff0c;则会直接新建一个用户。 比如 grant select,insert,delete,drop on atguigudb.…

驱动开发,stm32mp157a开发板的led灯控制实验

1.实验目的 编写LED灯的驱动&#xff0c;在应用程序中编写控制LED灯亮灭的代码逻辑实现LED灯功能的控制&#xff1b; 2.LED灯相关寄存器分析 LED1->PE10 LED1亮灭&#xff1a; RCC寄存器[4]->1 0X50000A28 GPIOE_MODER[21:20]->01 (输出) 0X50006000 GPIOE_ODR[10]-&g…

文件操作(个人学习笔记黑马学习)

C中对文件操作需要包含头文件<fstream > 文件类型分为两种: 1.文本文件&#xff1a;文件以文本的ASCII码形式存储在计算机中 2.二进制文件&#xff1a;文件以文本的二进制形式存储在计算机中&#xff0c;用户一般不能直接读懂它们 操作文件的三大类: 1.ofstream: 写操作 …