当前位置: 首页 > news >正文

C++实现日期类Date(超详细)

个人主页:平行线也会相交💪
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创
收录于专栏【C++之路】💌
本专栏旨在记录C++的学习路线,望对大家有所帮助🙇‍
希望我们一起努力、成长,共同进步。🍓
在这里插入图片描述

目录

  • 日期类(Date.cpp)成员函数的实现
    • 构造函数
    • bool类型的运算符重载
    • 得到该月有几天GetMonthDay
    • 运算符重载+=和+
    • 运算符重载-=和-
    • 运算符重载前置++和后置++
    • 运算符重载前置--后置--
    • 两个日期相差几天
  • 日期类(Date.h)
  • 日期测试
    • TestDate1()
    • TestDate2()
    • TestDate3()
    • TestDate4()
    • TestDate5()
    • TestDate6()

日期类(Date.cpp)成员函数的实现

//构造函数,声明和定义分析不能同时给缺省参数,一般是声明给缺省参数
Date::Date(int year, int month, int day)
{if (month > 0 && month < 13 && day>0 && day <= GetMonthDay(year, month)){_year = year;_month = month;_day = day;}else{cout << "非法日期" << endl;}
}bool Date::operator<(const Date& x)
{if (_year < x._year){return true;}else if (_year == x._year && _month < x._month){return true;}else if (_year == x._year && _month == x._month && _day < x._day){return true;}return false;
}bool Date::operator==(const Date& x)
{return _year == x._year&& _month == x._month&& _day == x._day;
}bool Date::operator<=(const Date& x)
{return *this < x || *this == x;
}bool Date::operator>(const Date& x)
{return !(*this <= x);
}bool Date::operator>=(const Date& x)
{return !(*this < x);
}bool Date::operator!=(const Date& x)
{return !(*this == x);
}int Date::GetMonthDay(int year, int month)
{//由于要频繁调用daysArr,所以我们把daysArr放到静态区static int daysArr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0) && month == 2)if (month == 2 && ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0))){return 29;}else{return daysArr[month];}return daysArr[month];
}//+=复用+
//Date& Date::operator+=(int day)
//{
//	*this = *this + day;
//	return *this;
//}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)
{Date tmp(*this);tmp += day;/*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;*///出了作用域后tmp销毁,所以不能用引用返回return tmp;
}Date& Date::operator -=(int day)
{if (day < 0){return *this += -day;}_day -= day;while (_day <= 0){--_month;if (_month == 0){_month = 13;--_year;}_day += GetMonthDay(_year, _month);}return *this;
}Date Date:: operator-(int day)
{Date tmp = *this;//这里是拷贝构造tmp -= day;return tmp;
}//前置++
Date& Date::operator++()
{*this += 1;return *this;
}//后置++
//增加int参数并不是为了接收具体的值,这里仅仅是占位,为了就是跟前置++构成重载
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;
}//两个日期相差几天
int Date::operator-(const Date& d)
{//默认认为第一个日期大,第二个小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::Date(int year, int month, int day)
{if (month > 0 && month < 13 && day>0 && day <= GetMonthDay(year, month)){_year = year;_month = month;_day = day;}else{cout << "非法日期" << endl;}
}

bool类型的运算符重载

bool Date::operator<(const Date& x)
{if (_year < x._year){return true;}else if (_year == x._year && _month < x._month){return true;}else if (_year == x._year && _month == x._month && _day < x._day){return true;}return false;
}bool Date::operator==(const Date& x)
{return _year == x._year&& _month == x._month&& _day == x._day;
}bool Date::operator<=(const Date& x)
{return *this < x || *this == x;
}bool Date::operator>(const Date& x)
{return !(*this <= x);
}bool Date::operator>=(const Date& x)
{return !(*this < x);
}bool Date::operator!=(const Date& x)
{return !(*this == x);
}

得到该月有几天GetMonthDay

int Date::GetMonthDay(int year, int month)
{//由于要频繁调用daysArr,所以我们把daysArr放到静态区static int daysArr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0) && month == 2)if (month == 2 && ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0))){return 29;}else{return daysArr[month];}return daysArr[month];
}

运算符重载+=和+

这里有两种方式来写+=和+的赋值运算符重载。

先来看第一种:+=复用+的方式,请看:

Date& Date::operator+=(int 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)
{Date tmp(*this);tmp += day;/*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;*///出了作用域后tmp销毁,所以不能用引用返回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;}}//出了作用域后tmp销毁,所以不能用引用返回return tmp;
}//+=复用+
Date& Date::operator+=(int day)
{*this = *this + day;return *this;
}

现在这两种写法哪一种好呢?对于每种方式的+的赋值运算符重载没啥太大的区别(都要都要创建两个对象,一个是Date tmp(*this);,另外一个就是return tmp);但是对于+=的赋值运算符重载,第一种方式并没有创建对象,而第二种方式的+=的符重运算符重载由于又调用了一次+的赋值运算符重载函数(即多创建了两个对象)。所以最终第一种方式(+复用+=)显然更好一些,第二种方式差就差再+=复用+的时候多创建了两个对象

运算符重载-=和-

Date& Date::operator -=(int day)
{if (day < 0){return *this += -day;}_day -= day;while (_day <= 0){--_month;if (_month == 0){_month = 13;--_year;}_day += GetMonthDay(_year, _month);}return *this;
}Date Date:: operator-(int day)
{Date tmp = *this;//这里是拷贝构造tmp -= day;return tmp;
}

运算符重载前置++和后置++

//前置++
Date& Date::operator++()
{*this += 1;return *this;
}//后置++
//增加int参数并不是为了接收具体的值,这里仅仅是占位,为了就是跟前置++构成重载,方便区分
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;
}

两个日期相差几天

//两个日期相差几天
int Date::operator-(const Date& d)
{//默认认为第一个日期大,第二个小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.h)

class Date
{
public://构造函数Date(int year = 22, int month = 5, int day = 20);//不需要写拷贝构造函数,所以下面可以选择直接注释掉Date (const Date& d){cout << "Date(const Date& d)" << endl;_year = d._year;_month = d._month;_day = d._day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}bool operator<(const Date& x);bool operator==(const Date& x);bool operator<=(const Date& x);bool operator>(const Date& x);bool operator>=(const Date& x);bool operator!=(const Date& x);int GetMonthDay(int year, int month);Date& operator+=(int day);Date operator+(int day);Date& operator -=(int day);Date  operator-(int day);Date& operator++();//前置++Date operator++(int);//后置++Date& operator--();//前置--Date operator--(int);//后置++//计算两个日期相差多少天int operator-(const Date& d);
private:int _year;int _month;int _day;
};

日期测试

TestDate1()

在这里插入图片描述

void TestDate1()
{Date da1(23, 5, 20);da1 += 100;da1.Print();Date da2(23, 5, 20);Date da3(da2 + 100);da2.Print();da3.Print();//用一个已经存在的对象初始化另一个对象,即拷贝构造函数//拷贝构造的意义就是赋值初始化Date da4 = da2;//等价于Date da4(da2);//均为拷贝构造函数,是等价的//而赋值重载的意义纯粹的就是拷贝//已经存在的两个对象之间进行复制拷贝,即运算符重载函数da4 = da1;
}

这里指的注意的是Date da4 = da2;是等价于Date da4(da2);,因为这里实在用一个已经存在的对象初始化另外一个对象,所以这里调用的是拷贝构造函数,而不是调用=的赋值运算符重载
如下如:
在这里插入图片描述
在这里插入图片描述

TestDate2()

{Date da1(2021, 5, 21);//无论前置还是后置++都需要++//前置++就返回++以后的对象,后置++就返回++之前的对象//编译器这里成全一个同时委屈一个,为了区分这里的重载++da1;//da1.operator++()da1++;//da1.operator++(0)Date da2(2024, 5, 20);Date da3(2023, 3, 14);bool ret1 = da2 < da3;//自定义类型转换为对应的函数int i = 0, j = 2;bool ret2 = i < j;//内置类型编译器知道怎么比较,故编译器会自动处理内置类型的重载
}

TestDate3()

//测试日期类的-=
void TestDate3()
{Date da1(2023, 5, 20);da1 -= 50;da1.Print();Date da2(2023, 5, 21);da2 -= 88;da2.Print();Date da3(2023, 5, 25);da3 -= 100;da3.Print();Date da4(2024, 5, 20);da4 -= 10000;da4.Print();
}

TestDate4()

void TestDate4()
{Date d1(2020, 5, 20);d1 += 100;d1.Print();Date da2(2023, 5, 21);da2 += -100;da2.Print();Date da3(2023, 5, 5);da3 -= -100;da3.Print();
}

TestDate5()

void TestDate5()
{Date da1(2023, 5, 5);Date ret1 = da1--;//调用da1.operator(&da1,0);ret1.Print();da1.Print();Date da2(2023, 5, 5);Date ret2 = --da2;//调用da1.operator++(&da1);ret2.Print();da2.Print();
}

TestDate6()

void TestDate6()
{Date da1(2023, 5, 20);Date da2(2022, 5, 21);Date da3(1949, 10, 1);Date da4(2023, 5, 20);cout << da1 - da2 << endl;cout << da2 - da1 << endl;cout << da3 - da4 << endl;cout << da4 - da3 << endl;
}

好了,以上就是用C++来实现日期类。
就到这里,再见啦各位!!!

在这里插入图片描述

http://www.lryc.cn/news/69216.html

相关文章:

  • 实验室检验系统源码,集检验业务、质量控制、报告、统计分析、两癌等模块于一体
  • 学习RHCSA的day.03
  • 电子邮件协议(SMTP,MIME,POP3,IMAP)
  • Golang笔记:使用embed包将静态资源嵌入到程序中
  • ImportError: cannot import name ‘OldCsv‘ from ‘pyflink.table.descriptors‘
  • YouCompleteMe(YCM)安装
  • day33_css
  • 10个最流行的向量数据库【AI】
  • vite3+vue3 项目打包优化二 —— 依赖分包策略
  • 中国社科院与美国杜兰大学金融管理硕士——与时间赛跑,充分利用每一分钟
  • 什么是Dirichlet分布?
  • web前端开发需要哪些技术?学前端顺序千万千万不要搞错啦!
  • 【AFNetWorking源码(二)AFURLSessionManger和AFHTTPSessionManager】
  • 编程不头秃,Google「AI程序员」来了,聊天就能敲代码
  • 【数据结构与算法】基础数据结构
  • k8s系列(四)——资源对象
  • JavaScript如何使用for循环
  • (浙大陈越版)数据结构 第三章 树(上) 3.1 树和树的表示
  • 平抑风电波动的电-氢混合储能容量优化配置(Matlab代码实现)
  • #机器学习--重新看待线性回归
  • 亚马逊,shopee,lazada卖家如何组建自己的测评团队
  • flink cdc 用mybatis-plus写到mysql5.6
  • 【C++】模板的一点简单介绍
  • SpringCloud概述
  • Metal入门学习:GPU并行计算大数组相加
  • 关于在spyder,jupyter notebook下创建虚拟环境(pytorch,tensorflow)均有效
  • oracle 闪回恢复
  • LeetCode 322 零钱兑换
  • 面试篇SpringMVC是什么以及工作原理
  • jQuery-层级选择器