• C++初阶 日期类的实现(上)


    目录

    一、前置准备

    1.1获得每月的天数

    1.2获得每年的天数

    1.3构造函数,析构函数和拷贝构造函数

    二、日期与天数的+,-,+=,-=实现

    2.1+=运算符重载

    2.2+运算符的实现

    2.3-=运算符的实现

    2.4-运算符的实现

    三、++,--的实现

    3.1前置++,后置++的实现

    3.2前置--和后置--的实现

    四、下期预告


    前言:C++初阶系列,每一期博主都会使用简单朴素的语言将对应的知识分享给大家,争取让所有人都可以听懂,C++初阶系列会持续更新,上学期间将不定时更新,但总会更的

    一、前置准备

    1.1获得每月的天数

    每月的天数是一个很重要的东西,其中二月最为特殊,闰年的时候它是29,其余年份为28,我们可以使用数组的方式来进行操作,而这个数组的创建也是有讲究的,创建为13的长度最好。

    因为数组的下标从0开始,而日期是从1开始的,如此我们若是想要月份和数组的下标一一对应,就得放弃一个空间,所以我们创建的长度为13,创建完数组之后第一个下标的值给0即可,从下一个下标的值开始给月份对应的天数,给完之后再在外面对闰年的情况单独处理一下,最后返回对应月份的天数就完成了。

    1. int GetMonthDay(int year, int month)
    2. {
    3. int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
    4. if (_month == 2 && ((_year % 4 == 0 && _year % 100 != 0) || _year % 400 == 0))
    5. {
    6. return 29;
    7. }
    8. return arr[month];
    9. }

    1.2获得每年的天数

    这个操作比之前更加简单,判断下是否是闰年即可,不多说,直接上代码

    1. int GetYearDay(int year)
    2. {
    3. if ((_year % 4 == 0 && _year % 100 != 0) || _year % 400 == 0)
    4. return 366;
    5. return 365;
    6. }

    1.3构造函数,析构函数和拷贝构造函数

    这方面是很基本的,具体的实现过程我就不赘述了,如果有小伙伴不懂,可以去看看博主之前写的博客C++ 初阶 类和对象(中)-CSDN博客 C++初阶 类和对象(下)-CSDN博客

    注意:构造函数构造的日期不一定合法,可以来个判断语句,若非法,中止程序

    直接上代码

    1. Date(int year=1,int month=1,int day=1)
    2. //构造函数
    3. {
    4. if (year < 1 || month>12 || day > GetMonthDay(year, month))
    5. {
    6. cout << "日期非法,创建失败" << endl;
    7. exit(-1);//退出程序
    8. }
    9. _year = year;
    10. _month = month;
    11. _day = day;
    12. }
    13. Date(const Date&d1)
    14. //拷贝构造函数
    15. {
    16. _year = d1._year;
    17. _month = d1._month;
    18. _day = d1._day;
    19. }
    20. ~Date()
    21. //析构函数
    22. {
    23. _year = 0;
    24. _month = 0;
    25. _day = 0;
    26. }

    二、日期与天数的+,-,+=,-=实现

    2.1+=运算符重载

    目标:实现一个日期+天数,日期被修改为过了多少天的日期

    很多人第一次写会写成这样,而编译器报错是因为多了一个this指针过去,已经达到了三目运算符的操作了   因此我们只需要把Date d1去掉即可,但因为有this指针的存在,我们一样能对这个变量进行操作。

    实现这个之前我们可以写一个GetMonthDay函数来获得没一月份的天数,值得注意的一点是闰年时2月为29日,接着我们来讲讲实现思路,我们的返回值最好设置成Date&型的,因为+=操作的目标出了函数作用域在main中依然存在,因此使用Date&类型的返回值可以令编译器的效率得到提高。

    可以先在目标的_day上加上day,这样能方便之后的进位,比方说2023-11-16 +100就先处理成2023-11-116,之后通过GetMonthDay取得的具体进位数据来进行进位即可,这里就可以通过循环实现,当_day>GetMonthDay时意味着需要进位,因此可以以这个来作为循环是否继续的条件,之后的实现便只需要注意一些细节即可,比方说,月满12进1之类的。

    1. int GetMonthDay(int year, int month)
    2. {
    3. int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
    4. //之所以是13是为了更加符合日期的返回,一月就返回数组下标为1的值
    5. if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
    6. {
    7. return 29;
    8. }
    9. return arr[month];
    10. }
    11. Date& operator +=(int day)
    12. {
    13. _day += day;
    14. while (_day > GetMonthDay(_year,_month))
    15. {
    16. _day -= GetMonthDay(_year, _month);
    17. _month++;
    18. if (_month>12)
    19. {
    20. _month = 1;
    21. _year++;
    22. }
    23. }
    24. return *this;
    25. }

    测试: 

    2.2+运算符的实现

    有了+=运算符之后+运算符就很好操作了,复用一下就好 

    使用临时变量的原因是因为,+运算符并不改变原来变量的值,比方说a=b+100;这里的b也不会被修改

    1. Date operator+(int day)
    2. {
    3. Date tmp(*this);
    4. tmp += day;
    5. return tmp;
    6. }

    2.3-=运算符的实现

     这个实现起来和+=有着异曲同工之处,都可以先直接在对象的_day上-day,比方说2023-11-17-100,就直接先转换为2023-11-(-83),然后通过月份的进位来不断的令_day增加,直到_day大于0的时候循环停止并返回对应的内容即可。

    注意:月份和天数在进行--的时候是不可能出现0的,大家应该都没听过0天,0月这种说法吧,因此在条件判断语句中应该要把0也考虑进去。

    1. Date& operator-=(int day)
    2. {
    3. _day -= day;
    4. while (_day <= 0)
    5. {
    6. _day += GetMonthDay(_year, _month);
    7. _month--;
    8. if (_month <= 0)
    9. {
    10. _month = 12;
    11. _year--;
    12. }
    13. }
    14. return *this;
    15. }

    测试:

    2.4-运算符的实现

    如+运算符一样简单的复用一下即可

    1. Date operator-(int day)
    2. {
    3. Date tmp(*this);
    4. tmp -= day;
    5. return tmp;
    6. }

    三、++,--的实现

    3.1前置++,后置++的实现

    有了+=和+运算符之后做这步是很简单的,唯一需要注意的是后置++的那个++运算符在重载的时候参数中要多来个int,注意:前置++,先++后使用,后置++先使用后++

    关于这方面更详细的讲解请看博主之前写的文章 

    C++初阶 类和对象(下)-CSDN博客

    1. Date& operator++()
    2. //前置++,先++后使用
    3. {
    4. (*this) += 1;
    5. return *this;
    6. }
    7. Date operator++(int)
    8. //后置++,先使用后++
    9. {
    10. Date tmp(*this);
    11. *this += 1;
    12. return tmp;
    13. }

    测试:

    3.2前置--和后置--的实现

    与++的实现几乎一样,不再赘述

    1. Date& operator--()
    2. {
    3. (*this) -= 1;
    4. return *this;
    5. }
    6. Date operator--(int)
    7. {
    8. Date tmp(*this);
    9. *this -= 1;
    10. return tmp;
    11. }

    测试:

    四、下期预告

    内容有点多,博主就拆成两篇文章了,大概今晚发 

  • 相关阅读:
    nginx(五十三)nginx中使用的PCRE正则
    KBQA知识图谱问答
    如何基于YAML设计接口自动化测试框架?看完秒会
    523. 连续的子数组和 (前缀和 + 同余性质+哈希)
    java计算机毕业设计小王防疫副食品配送商城源程序+mysql+系统+lw文档+远程调试
    mac为什么不支持ntfs,mac读取ntfs移动硬盘软件有哪些
    Java集合框架-Collection-List-vector(遗留类)
    疏水18碳磷脂磷脂-聚乙二醇-羧基,DSPE-PEG-Acid,CAS:1403744-37-5
    自制操作系统日志——第十一天
    Sharding-JDBC概述
  • 原文地址:https://blog.csdn.net/fq157856469/article/details/134449795