时间类的实现

在现实生活中,我们常常需要计算某一天的前/后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.xdnf.cn/news/20222.html

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

相关文章

Leetcode 路径总和

使用递归算法 class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {// 如果节点为空&#xff0c;返回falseif (root null) {return false;}// 如果是叶子节点&#xff0c;检查路径和是否等于目标值if (root.left null && root.right null) …

Linux开发讲课50--- epoll、poll、select的原理和区别

一、什么是epoll&#xff1f; epoll是一种I/O事件通知机制&#xff0c;是linux 内核实现IO多路复用的一个实现。IO多路复用是指&#xff0c;在一个操作里同时监听多个输入输出源&#xff0c;在其中一个或多个输入输出源可用的时候返回&#xff0c;然后对其的进行读写操作。 ep…

MySQL datetime不同长度的影响

MySQL datetime长度的影响 1.背景 MySQL数据库中某张表的某个字段类型设置datetime, 长度为0&#xff0c;在进行插入数据时&#xff0c;MySQL会对该字段进行舍入操作。 2.测试 1.创建一张测试表&#xff0c;里面有两个时间字段都是datetime&#xff0c;但其中一个长度为3 …

数据灾备方案学习

1. 数据灾备 1.1 备份 将数据由一份数据转存为多份数据的过程&#xff0c;即为备份&#xff0c;通常指将数据通过某些手段&#xff0c;将数据存放到其他不同设备中&#xff0c;防止数据丢失。指用户为应用系统产生的重要数据&#xff08;或者原有的重要数据信息&#xff09;制…

在centos7中安装SqlDeveloper的Oracle可视化工具

1.下载安装包 &#xff08;1&#xff09;在SqlDeveloper官网下载&#xff08;Oracle SQL Developer Release 19.2 - Get Started&#xff09;对应版本的安装包即可&#xff08;安装包和安装命令如下&#xff09;&#xff1a; &#xff08;2&#xff09;执行完上述命令后&#x…

矩阵论在深度学习中的应用

摘要&#xff1a; 本文深入探讨了矩阵论在深度学习领域的广泛应用。首先介绍了深度学习中数据表示和模型结构与矩阵的紧密联系&#xff0c;接着详细阐述了矩阵论在神经网络训练算法优化、卷积神经网络&#xff08;CNN&#xff09;、循环神经网络&#xff08;RNN&#xff09;及其…

AlphaFold 3开源,谷歌DeepMind诺奖AI项目,革新蛋白质结构预测,加速新药和疫苗研发

AlphaFold 3是什么&#xff1f; MeoAI了解到这个模型在2024年因其在蛋白质结构预测方面的贡献获得了诺贝尔化学奖。AlphaFold 3 是由 DeepMind 开发的一款人工智能&#xff08;AI&#xff09;软件&#xff0c;它能够以前所未有的精确度预测几乎所有生命大分子&#xff08;蛋白…

Excel如何把两列数据合并成一列,4种方法

Excel如何把两列数据合并成一列,4种方法 参考链接:https://baijiahao.baidu.com/s?id=1786337572531105925&wfr=spider&for=pc 在Excel中,有时候需要把两列或者多列数据合并到一列中,下面介绍4种常见方法,并且提示一些使用注意事项,总有一种方法符合你的要求:…

甲骨文云服务器 (Oracle Cloud) 终极防封、防回收的教程!

1.WindTerm 远程终端连接器&#xff1a;【官方下载】、【备用下载 】 2.AA面板&#xff1a;【安装脚本】 3.开启端口&#xff1a; sudo iptables -P INPUT ACCEPT sudo iptables -P FORWARD ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -F 4.WordPress&#xf…

c++源码阅读__ThreadPool__正文阅读

一. 简介 本章我们开始阅读c git 高星开源项目ThreadPool, 这是一个纯c的线程池项目, 并且代码量极小, 非常适合新手阅读 git地址: progschj / ThreadPool 二. 前提知识 为了面对不同读者对c掌握情况不同的情况, 这里我会将基本上稍微值得一说的前提知识点, 全部专门写成一篇…

环形子数组的最大和

题目 给定一个长度为 n 的环形整数数组 nums &#xff0c;返回 nums 的非空 子数组 的最大可能和 。 环形数组 意味着数组的末端将会与开头相连呈环状。形式上&#xff0c; nums[i] 的下一个元素是 nums[(i 1) % n] &#xff0c; nums[i] 的前一个元素是 nums[(i - 1 n) % …

二叉搜索树的基本操作(最全面)

目录 二叉搜索的定义: 节点类: 查找关键词对应的值: 非递归 递归: 查找最小关键词对应的值: 方法一: 方法二: 查找最大关键词对应的值: 方法一: 方法二: 存贮关键词对应的值: 查找关键词的前驱值: 查找关键词对应的后继值: 删除节点: 非递归: 递归: 范围 1.…

python爬虫-爬虫常用函数及其用法-1

1、urllib库 urllib库是python中一个最基本的网络请求库。可以模拟浏览器的行为&#xff0c;向指定的服务器发送一个请求&#xff0c;并可以保存服务器返回的数据。 &#xff08;1&#xff09;urlopen函数 在 python3 的 urllib 库中&#xff0c;所有和网络请求相关的方法&a…

vue3 路由守卫

在Vue 3中&#xff0c;路由守卫是一种控制和管理路由跳转的机制。它允许你在执行导航前后进行一些逻辑处理&#xff0c;比如权限验证、数据预取等&#xff0c;从而增强应用的安全性和效率。路由守卫分为几种不同的类型&#xff0c;每种类型的守卫都有其特定的应用场景。 其实路…

web——sqliabs靶场——第八关——sqlmap的使用

第八关还是用到了盲注&#xff0c;我们来使用kali里的sqlmap工具来搞一下。 1.sqlmap简介 sqlmap 是一款开源的自动化 SQL 注入和数据库接管工具&#xff0c;旨在帮助安全研究人员和渗透测试人员检测和利用 SQL 注入漏洞。它支持多种数据库管理系统&#xff08;如 MySQL、Post…

如何去掉el-input 中 type=“number“两侧的上下按键

<el-input v-model.trim"row.length" type"number" min"0" placeholder""></el-input> // 如何去掉el-input-number两侧的上下按键 ::v-deep input::-webkit-outer-spin-button, ::v-deep input::-webkit-inner-spin-butt…

【Redis】redis缓存击穿,缓存雪崩,缓存穿透

一、什么是缓存&#xff1f; 缓存就是与数据交互中的缓冲区&#xff0c;它一般存储在内存中且读写效率高&#xff0c;提高响应时间提高并发性能&#xff0c;如果访问数据的话可以先访问缓存&#xff0c;避免数据查询直接操作数据库&#xff0c;造成后端压力过大。 但是可能会面…

统⼀数据返回格式快速⼊⻔

为什么会有统⼀数据返回&#xff1f; 其实统一数据返回是运用了AOP&#xff08;对某一类事情的集中处理&#xff09;的思维。 优点&#xff1a; 1.⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。 2.降低前端程序员和后端程序员的沟通成本&#xff0c;因为所有接⼝都…

第7章硬件测试-7.6 量产可靠性测试

7.6 量产可靠性测试 7.6.1 生产小批量测试7.6.2 装备测试7.6.3 器件一致性测试7.6.4 工艺规程和单板维修技术说明 产品量产阶段需要通过可靠性测试来保障产品的可靠性。 7.6.1 生产小批量测试 生产小批量测试是发货之前的批量压力测试&#xff0c;有两个目的&#xff1a;一是…

可编辑的 SALV 模型(克服 SALV 模型的限制)

我们都知道 ABAP Object 比传统的 ABAP 非常强大。在这里&#xff0c;我想分享我使用 ABAP 对象克服 SALV mdoel 限制的最佳实验之一。 起源 最初&#xff0c;我在 SCN 上发布了这篇文章 – ABAP 对象的强大功能&#xff1a;克服 SALV 模型的限制&#xff0c;它也受到了很多批…