时间类的实现

在现实生活中,我们常常需要计算某一天的前/后xx天是哪一天,算起来十分麻烦,为此我们不妨写一个程序,来减少我们的思考时间。

1.基本实现过程

为了实现时间类,我们需要将代码写在3个文件中,以增强可读性,我们将这三个文件命名为date.h date.cpp test.cpp.

这是date.h文件

#pragma once 
#include<iostream>
using namespace std;class Date
{//友元friend void operator<<(ostream& out, const Date& d);
public:Date(int year = 1, int month = 1, int day = 1);void print();//inlineint getmonday(int year, int month){//把12个月先准备好static int monthDayArray[13] = { -1, 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 monthDayArray[month];}//判断日期大小的函数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);bool operator!=(const Date& d);//d1+=Date& operator+=(int day);Date operator+(int day);// d1 -=Date& operator-=(int day);// d1 - 100Date operator-(int day);// d1 - d2int operator-(const Date& d);// ++d1 -> d1.operator++();Date& operator++();// d1++ -> d1.operator++(0);Date operator++(int);Date& operator--();Date operator--(int);//void operator<<(ostream& out);private:int _year;int _month;int _day;
};
void operator<<(ostream& out, const Date& d);

这是date.cpp文件

#define _CRT_SECURE_NO_WARNINGS 
#include"date.h"
Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
void Date::print()
{cout << _year << "-" << _month << "-" << _day << endl;
}
//d1+=50
Date& Date::operator+=(int day)   //this  ->  d1;day->50
{if (day < 0){return *this -= (-day);}_day += day;        //等价于this->_day += day;while (_day > getmonday(_year, _month)){_day -= getmonday(_year, _month);//月进位++_month;if (_month == 13){++_year;_month = 1;}}return *this;
}Date Date::operator+(int day)
{Date tmp(*this);tmp += day;return tmp;
}
// d1 -= 天数
Date& Date::operator-=(int day)
{if (day < 0){return *this += (-day);}_day -= day;while (_day <= 0){// 借位--_month;if (_month == 0){--_year;_month = 12;}_day += getmonday(_year, _month);}return *this;
}
Date Date::operator-(int day)
{Date tmp = *this;tmp -= day;return tmp;
}
// d1 < d2
bool Date::operator>(const Date& 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){return _day > d._day;}return false;
}//d1<d2
bool Date::operator<(const Date& d)
{return !(*this >= d);              //复用,< 就是不大于
}
bool Date::operator<=(const Date& d)
{return !(*this > d);
}
// d1 >= d2
bool Date::operator>=(const Date& d)
{return *this > d || *this == d;
}
bool Date::operator==(const Date& d)
{return _year == d._year&& _month == d._month&& _day == d._day;
}
bool Date::operator!=(const Date& d)
{return !(*this == d);
}//顺便说一下前置++和后置++怎末写
// ++d1 -> d1.operator++();
Date& Date::operator++()
{*this += 1;return *this;
}
// d1++ -> d1.operator++(0);//这个数多少都行,没影响的,就是++,跟你传的数没关系
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
//this->d1,d->d2    (d是d2别名)
int	Date::operator-(const Date& d)
{//不知道d1d2谁大谁小,为了避免弄错先后关系,我们比较一下int flag = 1;Date max = *this;Date min = d;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max){++n;++min;}return n * flag;
}
void operator<<(ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
}

这是test.cpp文件

#include"Date.h"
#include<math.h>
void testdate1()
{Date d1(2024, 11, 14);Date d2 = d1 + 50;//d1 += 50;d1.print();d2.print();Date d3(2024, 11, 14);Date d4 = d3 + 5000;d3 += 5000;d3.print();d4.print();
}
void testdate2()
{Date d1(2024, 11, 16);Date d2 = d1 - 50;//d1 -= 50;d1.print();d2.print();Date d3(2024, 11, 16);Date d4 = d3 - 5000;d3 -= 5000;d3.print();d4.print();Date d5(2024, 11, 16);d5 += -100;d5.print();
}
void testdate3()
{Date d1(2024, 11, 16);Date d2(2024, 11, 16);Date d3(2024, 10, 17);cout << (d1 > d2) << endl;cout << (d1 >= d2) << endl;cout << (d1 == d2) << endl;cout << (d1 > d3) << endl;cout << (d1 >= d3) << endl;cout << (d1 == d3) << endl;
}
void testdate4()
{//打印时,不要放在一坨,否则由于我们的++操作,可能导致程序本身没大问题,但是打印会出问题,导 致我们看不到我们想要的结果Date d1(2024, 11, 16);d1.print();Date d4 = d1++;   //等价于Date d4 = d1.operator++(1);这里实参传什么值都可以,只要是int就 行,仅仅参数匹配d4.print();Date d3 = ++d1;   //等价于Date d3 = d1.operator++();d3.print();cout << endl;Date d6(2024, 11, 16);d6.print();Date d7 = ++d6;d7.print();Date d8 = d6++;d8.print();//通过对比两组实验结果,我们发现,前置++和后置++区别很大,//第一组,我们让后置++在前置++前面,会发现:由于后置++是先使用后++,故打印出16日,之后变为 17,而前置++是先++后使用,此时,17+1==18,故打印出来是18日//同理,可解释第二组的结果,这里不在赘述,由此可见,选取哪种++方式,要视情况而定
}
void testdate5()
{Date d1(2025, 3, 3);Date d2(2025, 1, 14);cout <<"还有" << abs(d1 - d2) <<"放假!"<< endl;    //abs是临时起意为了解决实际问题而加的int i = 100;//cout << d1 << "和" << i;cout << d1;     //这里之所以能输出年月日字样,是因为我们定义了<<运算符,是设置的一种输出流, 不要和正常的cout<<弄混//d1 << cout;
}
int main()
{//testdate1();//testdate2();//testdate3();//testdate4();testdate5();return 0;
}

代码结果这里就不过多展示了!

2.代码优化 

这里有一个小问题~~

上述testdate5中,cout<<d1没有问题,但是当我们在想连续输出其他值时,会出现报错,我们看<ostream>里面的cout,为什么可以连续输出,因为其在输出第一个值之后,返回值仍为cout,但是,反观我们写的函数,没有返回值了!故我们需要在对其精进一下!

精进代码如下:

我们将date.cpp的输入流和输出流这样改一下!

ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}
istream& operator>>(istream& in, Date& d)
{cout << "请依次输入年月日:>";in >> d._year >> d._month >> d._day;return in;
}

date.h也改一下:(这里将前面用不到的函数删去了!)

#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:
private:int _year;int _month;int _day;
};
// 流插入
ostream& operator<<(ostream& out, const Date& d);
// 流提取
istream& operator>>(istream& in, Date& d);

test.cpp也改一下:

void testdate6()
{Date d1(2024, 2, 29);Date d2(2023, 2, 29);cin >> d1 >> d2;cout << d1 << d2;
}
int main()
{testdate6();return 0;
}

如此一来,我们得到了我们想输出的日期! 

 

 可是,这个日期真的对吗?我们的编译器似乎太服从我们了,不管对错他都输出,但是,为了保证我们输出结果的正确性,应该加上一组日期判断,不符合常理的就让用户重新输!

3.提高正确性

我们做出如下改造:

在date.cpp文件中在定义一个函数,用于检查日期是否合理:

bool Date::checkdate()const     //为什么加const下一篇博客讲
{if (_month < 1 || _month > 12 || _day < 1 || _day > getmonday(_year, _month)){return false;}else{return true;}
}

date.cpp的流提取也要改一下: 

istream& operator>>(istream& in, Date& d)
{while (1){cout << "请依次输入年月日:>";in >> d._year >> d._month >> d._day;if (d.checkdate())        //得到结果为1{break;}else                     //得到结果为0{cout << "输入的日期非法,请重新输入" << endl;}}return in;
}

这样我们就得到了一个功能相对健全的时间程序!

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

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

相关文章

php交友源码交友系统源码相亲交友系统源码php社交系统php婚恋源码php社区交友源码vue 仿交友社交语聊技术栈

关于PHP交友、相亲、婚恋、社区交友系统的源码以及Vue仿交友社交语聊技术栈&#xff0c;以下是一些详细信息和建议&#xff1a; 一、PHP交友系统源码 系统架构设计 前端展示层&#xff1a;负责向用户提供直观友好的界面&#xff0c;包括注册登录页面、个人资料页面、匹配页面、…

Java小技艺

使用bat文件启动jar包 平时在工作中运行jar包一般是导出后命令行窗口运行 jar -jar xxx.jar 这个其实是很不方便的。可以在win上编写bat脚本去运行jar包的。 1 编写bat脚本 start jre8/bin/javaw -jar xxxx.jar2 将jre和待执行的jar包存放到一个目录下(和bat文件在同一目录…

蓝桥杯第22场小白入门赛2~5题

这场比赛开打第二题就理解错意思了&#xff0c;还以为只能用3个消除和5个消除其中一种呢&#xff0c;结果就是死活a不过去&#xff0c;第三题根本读不懂题意&#xff0c;这蓝桥杯的题面我只能说出的是一言难尽啊。。第四题写出来一点但是后来知道是错了&#xff0c;不会正解&am…

‘视’不可挡:OAK相机助力无人机智控飞行!

南京邮电大学通达学院的刘同学用我们的oak-d-lite实现精确打击无人机的避障和目标识别定位功能&#xff0c;取得了比赛冠军。我们盼望着更多的朋友们能够加入到我们OAK的队伍中来&#xff0c;参与到各式各样的比赛中去。我们相信&#xff0c;有了我们相机的助力&#xff0c;大家…

最小生成树——Kruskal、Prim算法

图的存储&#xff1a; 高阶数据结构——图 文章目录 目录 文章目录 一、kruskal算法 二、Prim算法 前言 连通图中的每一棵生成树&#xff0c;都是原图的一个极大无环子图&#xff0c;即&#xff1a;从其中删去任何一条边&#xff0c;生成树 就不在连通&#xff1b;反之&#xf…

集群聊天服务器(9)一对一聊天功能

目录 一对一聊天离线消息服务器异常处理 一对一聊天 先新添一个消息码 在业务层增加该业务 没有绑定事件处理器的话消息会派发不出去 聊天其实是服务器做一个中转 现在同时登录两个账号 收到了聊天信息 再回复一下 离线消息 声明中提供接口和方法 张三对离线的李…

华为再掀技术革新!超薄膜天线设计路由器首发!

随着Wi-Fi技术的不断进步&#xff0c;新一代的Wi-Fi 7路由器凭借其高速率、低延迟、更稳定的性能受到了广泛关注。它能够更好地满足现代家庭对网络性能的高要求&#xff0c;带来更加流畅、高效的网络体验。9月24日&#xff0c;华为在其秋季全场景新品发布会上推出了全新Wi-Fi 7…

【阅读记录-章节2】Build a Large Language Model (From Scratch)

目录 2.Working with text data2.1 Understanding word embeddings2.2 Tokenizing text通过一个简单的实验来理解文本的词元化概念关键概念 2.3 Converting tokens into token IDs实现分词器类&#xff08;Tokenizer Class&#xff09;应用分词器测试文本的编码与解码通过分词器…

SDF,一个从1978年运行至今的公共Unix Shell

关于SDF 最近发现了一个很古老的公共Unix Shell服务器&#xff0c;这个项目从1978年运行至今&#xff0c;如果对操作系统&#xff0c;对Unix感兴趣&#xff0c;可以进去玩一玩体验一下 SDF Public Access UNIX System - Free Shell Account and Shell Access 注册方式 我一…

关于Qt C++中connect的几种写法

目录 1. 传统的槽函数写法 2. 使用函数指针的connect写法&#xff08;5.0&#xff09; 3. Lambda表达式作为槽函数&#xff08;C11&#xff09; 4.使用QOverload选择重载信号的写法 这connect函数就像是编程世界里的“茴”字&#xff0c;千变万化&#xff0c;各有千秋。咱们…

反向代理模块

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当于…

用jquery做一个websocket客户端

先看效果图&#xff1a; 功能很简单&#xff0c;就是作为客户端连接websocket&#xff0c;并实现接受和发送消息。具体代码如下&#xff1a; <!DOCTYPE html> <html lang"zh-cn"> <head><meta charset"UTF-8"><meta name"…

抽象java入门1.5.3.2——类的进阶(中)

前期回顾&#xff1a;抽象java入门1.5.3.1——类的进阶https://blog.csdn.net/c_yanxin_ru/article/details/140858898?spm1001.2014.3001.5501 总结&#xff1a; 在代码溯源中&#xff0c;我发现了一个奇怪的东西&#xff0c;就是OUT不是类中类&#xff08;不是常规类的写法…

蓝桥杯每日真题 - 第17天

题目&#xff1a;&#xff08;最大数字&#xff09; 题目描述&#xff08;13届 C&C B组D题&#xff09; 题目分析&#xff1a; 操作规则&#xff1a; 1号操作&#xff1a;将数字加1&#xff08;如果该数字为9&#xff0c;变为0&#xff09;。 2号操作&#xff1a;将数字…

Ease Monitor 会把基础层,中间件层的监控数据和服务的监控数据打通,从总体的视角提供监控分析

1. 产品定位 Ease Monitor 有如下的产品定位&#xff1a; 关注于整体应用的SLA。 主要从为用户服务的 API 来监控整个系统。 关联指标聚合。 把有关联的系统及其指示聚合展示。主要是三层系统数据&#xff1a;基础层、平台中间件层和应用层。 快速故障定位。 对于现有的系统…

3D Gaussian Splatting 代码层理解之Part2

现在让我们来谈谈高斯分布。我们已经在Part1介绍了如何根据相机的位置获取 3D 点并将其转换为 2D。在本文中,我们将继续处理高斯泼溅的高斯部分,这里用到的是代码库 GitHub 中part2。 我们在这里要做的一个小改动是,我们将使用透视投影,它利用与上一篇文章中所示的内参矩阵…

一道算法期末应用题及解答

1&#xff0e;印刷电路板布线区划分成为n m 个方格&#xff0c;确定连接方格a 到方格b 的最短布线方案。 在布线时&#xff0c;只能沿直线或者直角布线&#xff0c;为避免交叉&#xff0c;已经布线的方格做了封锁标记&#xff0c;其他线路不允许穿过被封锁的方格&#xff0c;某…

揭开广告引擎的神秘面纱:如何在0.1秒内精准匹配用户需求?

目录 一、广告系统与广告引擎介绍 &#xff08;一&#xff09;广告系统与广告粗分 &#xff08;二&#xff09;广告引擎在广告系统中的重要性分析 二、广告引擎整体架构和工作过程 &#xff08;一&#xff09;一般概述 &#xff08;二&#xff09;核心功能架构图 三、标…

freertos任务调度学习

首先创建任务&#xff0c;创建好任务后&#xff0c;开启任务调度器&#xff0c;任务才能执行 1.开启任务调度器 2.启动第一个任务 3.任务切换