C++初阶——日期类的实现

目录

1、Date.h

2、注意

3、Date.cpp 实现

4、test.cpp 测试用例


日期类的实现是为了巩固C++初阶——类和对象(上)(中)的知识点

1、Date.h

#pragma once
#include <iostream>
using namespace std;
#include <assert.h>class Date
{// 友元函数,C++初阶——类和对象(下)friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
public:// 全缺省的构造函数Date(int year = 1900, int month = 1, int day = 1);// 拷贝构造函数// d2(d1)Date(const Date& d);// 赋值运算符重载// d2 = d3 -> d2.operator=(&d2, d3)Date& operator=(const Date& d);// 析构函数~Date();// 获取某年某月的天数int GetMonthDay(int year, int month) const{assert(month > 0 && month < 13);int month_arr[] = { -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))//  month == 2 更容易判断return 29;elsereturn month_arr[month];}bool CheckDate() const;void Print() const;// 日期+=天数Date& operator+=(int day);// 日期+天数Date operator+(int day) const;// 日期-天数Date operator-(int day) const;// 日期-=天数Date& operator-=(int day);// 前置++Date& operator++();// 后置++Date operator++(int);// 后置--Date operator--(int);// 前置--Date& operator--();// >运算符重载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;// 日期-日期 返回天数int operator-(const Date& d) const;
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);

2、注意

对象可以调用类里的函数,类里的函数也调用类里的函数

默认构造函数的声明处有缺省值,定义处没有,防止声明和定义的缺省值不一致。

Date类没有需要释放的资源,所以不用显示实现析构函数,拷贝构造函数,赋值运算符重载函数。

GetMonthDay(_year,_month)  const

在类里成员函数默认为inline(多次调用的少量代码),const 使this指向的内容不能改变,声明定义一致加const。

日期-天数是,不够,借的是上个月的天数。

对_month,++--后都要进行判断。

因为 日期-天数 和 日期-=天数,非常相似,-调用了-=,进行复用,

其实也可以-=调用-,但多了两次拷贝构造和一次赋值

左-=调用-                                                               右-调用-=

对于比较运算符,可以先实现完>和=或者<和=根据逻辑运算符,可以进行复用。

日期-日期,由于一般日期的就是几千年,及计算机CPU运算速度很快(上亿次),所以不用担心效率问题

重载<<和>>时,

若为成员函数,this指针抢占第一个参数的位置,只能 对象<<cout调用,不符合习惯,

所以作为全局函数,在类里将其声明为友元函数,即可使用对象的私有成员。

cout cin不支持拷贝构造,所以进行引用传递。

3、Date.cpp 实现

#include "date.h"bool Date::CheckDate() const
{if (_month < 1 || _month>12 || _day<1 || _day>GetMonthDay(_year, _month))return false;elsereturn true;
}void Date::Print() const
{cout << _year << '/' << _month << '/' << _day << endl;
}// 全缺省的构造函数
Date::Date(int year, int month, int day)// 只在声明处给缺省值,防止声明和定义的缺省值不一致
{_year = year;_month = month;_day = day;if (!CheckDate())// 成员函数,默认前面有this.,第一个参数为this{cout << "非法日期";Print();}
}// 拷贝构造函数
// d2(d1)
Date::Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& Date::operator=(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;return *this;
}// 析构函数
Date::~Date()
{;//无资源释放
}// 日期+=天数
Date& Date::operator+=(int day)
{if (day < 0){*this -= (-day);}else{_day += day;// 日期变了int d;while (_day > (d = GetMonthDay(_year, _month)))// 其实是this->GetMonthDay(){_day -= d;// 减这个月的天数++_month;if (_month > 12){_month = 1;++_year;}}}return *this;// 日期对象出了函数还存在,传引用返回,减少拷贝
}// 日期+天数
Date Date::operator+(int day) const
{Date tmp = *this;// 日期没有变tmp += day;return tmp;// tmp为局部变量,值返回
}// 日期-=天数
Date& Date::operator-=(int day)
{if (day < 0){*this += (-day);}else{_day -= day;// 日期变了while (_day <= 0){--_month;// 加上个月的天数,因为要借上个月的天数if (_month < 1){_month = 12;--_year;}_day += GetMonthDay(_year, _month);}}return *this;// 日期对象出了函数还存在,传引用返回,减少拷贝
}// 日期-天数
Date Date::operator-(int day) const
{Date tmp = *this;// 日期没有变tmp -= day;return tmp;// tmp为局部变量,值返回
}// 前置++
Date& Date::operator++()
{*this = *this + 1;return *this;
}// 后置++
Date Date::operator++(int)
{Date tmp = *this;*this = *this + 1;return tmp;
}// 前置--
Date& Date::operator--()
{*this = *this - 1;return *this;
}// 后置--
Date Date::operator--(int)
{Date tmp = *this;*this = *this - 1;return tmp;
}// >运算符重载
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;}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);
}// 日期-日期 返回天数
// *this-d
int Date::operator-(const Date& d) const
{int flag = -1;Date min = *this;Date max = d;if (max < min){flag = 1;min = d;max = *this;}int n = 0;while (min<max){++min;++n;}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 << "请依次输入年月日:>";//不用担心会被读到,cin会刷新cout的缓冲区in >> d._year >> d._month >> d._day;if (!d.CheckDate()){cout << "输入非法日期:";d.Print();cout << "请输入正确日期!!!" << endl;}else{break;}}return in;
}

4、test.cpp 测试用例

#include "date.h"void test1()
{Date d1(2024, 11, 16);Date d2(d1);Date d3;d3 = d1;d1.Print();d2.Print();d3.Print();//d1 += 10000;//d2 -= 10000;//d1.Print();//d2.Print();//d1 += -10000;//d2 -= -10000;//d1.Print();//d2.Print();//d2 = d1 + -10000;//d2.Print();//d3 = d1 + 10000;//d3.Print();
}void test2()
{Date d1(2024, 11, 16);Date d2(2024, 11, 16);d1.Print();d2.Print();Date ret1 = d1++;ret1.Print();d1.Print();Date ret2 = ++d2;ret2.Print();d2.Print();
}void test3()
{Date d1(2024, 11, 16);Date d2(2024, 7, 12);d1.Print();d2.Print();cout << d1 - d2 << endl;
}void test4()
{Date d1, d2;cin >> d1 >> d2;cout << d1 << d2 << endl;cout << d1 - d2 << endl;
}int main()
{test4();return 0;
}

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

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

相关文章

rust高级特征

文章目录 不安全的rust解引用裸指针裸指针与引用和智能指针的区别裸指针使用解引用运算符 *&#xff0c;这需要一个 unsafe 块调用不安全函数或方法在不安全的代码之上构建一个安全的抽象层 使用 extern 函数调用外部代码rust调用C语言函数rust接口被C语言程序调用 访问或修改可…

【Linux系统编程】第四十六弹---线程同步与生产消费模型深度解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、Linux线程同步 1.1、同步概念与竞态条件 1.2、条件变量 1.2.1、认识条件变量接口 1.2.2、举例子认识条件变量 1.2.3、…

工作时发现自己手写SQL能力很低,特此再来学习一遍SQL

SQL语法 ①常用的数据库本身的操作 # 显示数据库列表 show databases;# 使用某个数据库 use twbpm_dev;# 创建一个数据库 create database db_test;# 删除一个数据库 drop database if exists db_test;# 显示数据库中所有的表 show tables;# 查看MySQL的版本 select version();…

华为Ensp模拟器配置RIP路由协议

目录 RIP路由详解&#xff1a;另一种视角解读 1. RIP简介&#xff1a;轻松理解基础概念 2. RIP的核心机制&#xff1a;距离向量的魅力 3. RIP的实用与局限 RIP配置实验 实验图 ​编辑 PC的ip配置 RIP配置步骤 测试 结语&#xff1a;RIP的今天与明天 RIP路由详解&…

控制器ThinkPHP6

五、控制器中对数组值的返回 在做接口服务时&#xff0c;很多时候回使用数组作为返回值&#xff0c;那么数组如何返回成 json呢&#xff1f; 在 tp6 中返回json 很简单&#xff0c;直接使用 json 进行返回即可&#xff0c;例如&#xff1a; public function index(){$resarra…

SAFETY LAYERS IN ALIGNED LARGE LANGUAGEMODELS: THE KEY TO LLM SECURITY

目录 概要 背景 大语言模型对齐 对齐大语言模型中的过度拒绝 微调攻击 研究设置 问题定义 对齐的大语言模型 大语言模型的提示模板 安全层的存在和定位 安全层的存在性 1.从余弦相似度说明 2.从向量之间角度差异说明 3.与预训练LLM对比说明 安全层的定位 1.推理…

营销手段的变革:开源 AI 智能名片与 S2B2C 商城小程序在新趋势下的机遇与挑战

摘要&#xff1a;本文探讨了在当今营销环境变化下&#xff0c;企业必须改变传统营销手段的必要性。分析了大环境造就的主流趋势对企业的要求&#xff0c;以及传统营销方式如邮件直投的局限性。着重阐述了移动营销的重要性&#xff0c;并进一步研究开源 AI 智能名片和 S2B2C 商城…

【SpringBoot】公共字段自动填充

问题引入 JavaEE开发的时候&#xff0c;新增字段&#xff0c;修改字段大都会涉及到创建时间(createTime)&#xff0c;更改时间(updateTime)&#xff0c;创建人(craeteUser)&#xff0c;更改人(updateUser)&#xff0c;如果每次都要自己去setter()&#xff0c;会比较麻烦&#…

网络安全练习之 ctfshow_web

文章目录 VIP题目限免&#xff08;即&#xff1a;信息泄露题&#xff09;源码泄露前台JS绕过协议头信息泄露robots后台泄露phps源码泄露源码压缩包泄露版本控制泄露源码(git)版本控制泄露源码2(svn)vim临时文件泄露cookie泄露域名txt记录泄露敏感信息公布内部技术文档泄露编辑器…

Git_2024/11/16

文章目录 前言Git是什么核心概念工作流程常见术语解读Git的优势 Git与SVN对比SVNGit总结 Git配置流程及指令环境配置获取Git仓库本地初始化远程克隆 工作目录、暂存区、版本库文件的两种状态本地仓库操作远程仓库操作Git分支Git标签IntelliJ IDEA使用Git回滚代码 GitHub配置流程…

游戏引擎学习第八天

视频参考: https://www.bilibili.com/video/BV1ouUPYAErK/ 理解下面的代码 关于虚函数 代码分解 结构体 foo 的定义&#xff1a; struct foo {int32 X;int64 Y;virtual void Bar(int c); };foo 结构体有两个成员变量&#xff1a;X&#xff08;int32 类型&#xff09;和 Y&…

蓝桥杯-洛谷刷题-day3(C++)

目录 1.忽略回车的字符串输入 i.getline() ii.逐个字符的识别再输入 2.获取绝对值abs() 3.做题时的误区 4.多个变量的某一个到达判断条件 i.max() 5.[NOIP2016 提高组] 玩具谜题 i.代码 6.逻辑上的圆圈 i.有限个数n的数组 7.数组的定义 i.动态数组 1.忽略回车的字符串输…

不用来回切换,一个界面管理多个微信

你是不是也有多个微信号需要管理&#xff1f; 是不是也觉得频繁切换账号很麻烦&#xff1f; 是不是也想提升多账号管理的效率&#xff1f; 在工作中&#xff0c;好的辅助工具&#xff0c;能让我们的效率加倍增长&#xff01; 今天&#xff0c; 就给大家分享一个多微管理工具…

Word_小问题解决_1

1.第二页是空白的&#xff0c;但是删不掉 将鼠标弄到第二页最开始的地方打开段落设置行距为固定值0.7磅 2.表格中有文字进入了表格中怎么办 打开段落&#xff0c;将缩进改为0即可

LLM - 计算 多模态大语言模型 的参数量(Qwen2-VL、Llama-3.1) 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/143749468 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 影响 (…

GEE下载ERA5-Land气象数据(1950-至今,降水、温度)

GEE下载ERA5-Land气象数据&#xff08;1950-至今&#xff0c;降水、温度&#xff09; ERA5-Land是一个高分辨率的陆地再分析数据集,相比ERA5数据集具有更高的空间分辨率。它是通过重新运行ECMWF ERA5气候再分析系统的陆地分量生成的。 空间分辨率特点&#xff1a; 网格间距…

动态规划-完全背包问题——518.零钱兑换II

1.题目解析 建议先看 322.零钱兑换可以 更加轻松的理解本题 题目来源 518.零钱兑换——力扣 测试用例 2.算法原理 1.状态表示 本题要求返回所有情况&#xff0c;所以dp值就代表所有的方法数&#xff0c;即 dp[i][j]&#xff1a;在[1,i]个硬币中选择不同面值的硬币&#xff0c…

推荐15个2024最新精选wordpress模板

以下是推荐的15个2024年最新精选WordPress模板&#xff0c;轻量级且SEO优化良好&#xff0c;适合需要高性能网站的用户。中文wordpress模板适合搭建企业官网使用。英文wordpress模板&#xff0c;适合B2C网站搭建&#xff0c;功能强大且兼容性好&#xff0c;是许多专业外贸网站的…

使用Java绘制图片边框,解决微信小程序map组件中marker与label层级关系问题,label增加外边框后显示不能置与marker上面

今天上线的时候发现系统不同显示好像不一样&#xff0c;苹果手机打开的时候是正常的&#xff0c;但是一旦用安卓手机打开就会出现label不置顶的情况。尝试了很多种办法&#xff0c;也在官方查看了map相关的文档&#xff0c;发现并没有给label设置zIndex的属性&#xff0c;只看到…

微信小程序 https://thirdwx.qlogo.cn 不在以下 downloadFile 合法域名列表中

授权登录后&#xff0c;拿到用户头像进行加载&#xff0c;但报错提示&#xff1a; https://thirdwx.qlogo.cn 不在以下 downloadFile 合法域名列表中 解决方法一&#xff08;未完全解决&#xff0c;临时处理&#xff09;&#xff1a;在微信开发者工具将不校验...勾上就可以访问…