日期类代码实现-C++

打印 上一主题 下一主题

主题 971|帖子 971|积分 2913

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、目标

        通过前面对类和对象的介绍我们可以自己通过C++代码初步实现一个简朴的日期类。
实现的主要操作有:
1.日期类的构造函数
2.日期类的拷贝构造函数(在头文件中实现)
3.日期类的比力运算符重载
4.日期类的计算运算符重载
5.流插入运算符重载。
二、总体思路

        首先,我这里接纳的是分文件编程的方式来实现的日期类。
分别为:
1.头文件:Date.h

        该文件的主要目的是对上述目标所要实现的所有操作进行函数的声明。同时,还要包含在
源文件Date.cpp 中界说时所需要用到的头文件函数。
2.源文件:Date.cpp

        该文件的目的主要是用于对 头文件Date.h 所声明的所有函数进行界说,从而完成各个函数所要实现的操作。
3.源文件:Test.cpp

        该文件的目的主要是用于检测 源文件Date.cpp 中界说的函数是否能正常够利用而且达到所要实现的操作。
三、代码实现及具体思路

1.头文件:Date.h

        通过上面思路的介绍,我们可以知道,我们的目的是创建一个日期类,然后在日期类中自我声明:日期类的构造函数、日期类的比力运算符重载、日期类的计算运算符重载以及流插入运算符重载。并实现拷贝构造函数。
留意:通过我们前面对类和对象的介绍可知,因为在实现日期类过程中,我们没有动态申请空间,所以我们只需利用编译器默认生成的析构函数就可以,因此,我们不需要自己再界说一个析构函数)
代码如下:
  1. #pragma once
  2. #include <iostream>
  3. #include <assert.h>
  4. using namespace std;
  5. class Date
  6. {
  7. public:
  8.         Date(int year = 1, int month = 1, int day = 1);
  9.         void Print()const
  10.         {
  11.                 cout << _year << '-' << _month << '-' << _day << endl;
  12.         }
  13.         Date(const Date& d)
  14.         {
  15.                 _year = d._year;
  16.                 _month = d._month;
  17.                 _day = d._day;
  18.         }
  19.         //日期类的比较运算符的重载
  20.         bool operator<(const Date& x) const;
  21.         bool operator==(const Date& x) const;
  22.         bool operator<=(const Date& x) const;
  23.         bool operator>(const Date& x) const;
  24.         bool operator>=(const Date& x) const;
  25.         bool operator!=(const Date& x) const;
  26.         //日期类的计算运算符的重载
  27.         int Get_MonthDay(int year,int month);                //获取该月份的天数
  28.         Date& operator+=(int day);
  29.         Date operator+(int day)const;
  30.         Date& operator-=(int day);
  31.         Date operator-(int day)const;
  32.         Date& operator++();                //前置++
  33.         Date operator++(int);                //后置++
  34.         Date& operator--();                        //前置--
  35.         Date operator--(int);                //后置--
  36.         int operator-(const Date& x) const;
  37.         // 流插入不能写成成员函数?
  38.         // 因为Date对象默认占用第一个参数,就是做了左操作数
  39.         // 写出来就一定是下面这样子,不符合使用习惯
  40.         //d1 << cout; // d1.operator<<(cout);
  41.         //void operator<<(ostream& out);
  42.        
  43.         // 友元函数声明
  44.         friend ostream& operator<<(ostream& out, const Date& d);
  45.         friend istream& operator>>(istream& in, Date& d);
  46. private:
  47.         int _year;
  48.         int _month;
  49.         int _day;
  50. };
  51. ostream& operator<<(ostream& out, const Date& x);
  52. istream& operator>>(istream& in, Date& x);
复制代码

2.源文件:Date.cpp

        对于实现下面函数,我们需要首先界说一个获取当前月份天数的函数
代码实现:
  1. //因为平年闰年的2月天数不一样所以我们需定义一个获取月份的函数来解决这一问题
  2. int Date::Get_MonthDay(int year, int month)                //获取该月份的天数
  3. {
  4.         static int daysArr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
  5.         if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
  6.         {
  7.                 return 29;
  8.         }
  9.         else
  10.         {
  11.                 return daysArr[month];
  12.         }
  13. }
复制代码
1.日期类的构造函数

 思路:
        我们在通过日期类构造函数初始化所界说的日期时,我们需要判定我们所界说的日期是否合法,若不合法,则需要返回并提示
代码实现:
  1. Date::Date(int year, int month, int day)
  2. {
  3.     //判断所初始化的日期是否合法
  4.         if (month > 0 && month < 13
  5.                 &&day>=1&&day<= Get_MonthDay(year, month))
  6.         {
  7.                 _year = year;
  8.                 _month = month;
  9.                 _day = day;
  10.         }
  11.         else
  12.         {
  13.                 cout << "非法日期" << endl;
  14.                 assert(false);
  15.         }
  16. }
复制代码
2.日期类的比力运算符重载

思路:
        对于比力类的运算符重载来说,因为比力运算符具有互斥性,所以我们只需界说出 < 运算符重载和 == 运算符重载,然后其他运算符复用上面所定界说的两个运算符即可。而且在比力的同时,我们不会改变参数的值,所以我们可以在函数尾部加const用于修饰内部的this指针,如许的话,const修饰的类型我们也可以通过比力运算符来比力。
代码实现:
  1. bool Date::operator<(const Date& x) const
  2. {
  3.         if (_year < x._year)
  4.         {
  5.                 return true;
  6.         }
  7.         else if (_year == x._year && _month < x._month)
  8.         {
  9.                 return true;
  10.         }
  11.         else if (_year == x._year && _month == x._month && _day < x._day)
  12.         {
  13.                 return true;
  14.         }
  15.         else
  16.         {
  17.                 return false;
  18.         }
  19. }
  20. bool Date::operator==(const Date& x) const
  21. {
  22.         if (_year == x._year && _month == x._month && _day == x._day)
  23.         {
  24.                 return true;
  25.         }
  26.         else
  27.         {
  28.                 return false;
  29.         }
  30. }
  31. bool Date::operator<=(const Date& x) const
  32. {
  33.         //复用上面定义的重载运算符:< , ==
  34.         return *this < x || *this == x;
  35. }
  36. bool Date::operator>(const Date& x) const
  37. {
  38.         //复用上面定义的重载运算符:<=
  39.         return !(*this <= x);
  40. }
  41. bool Date::operator>=(const Date& x) const
  42. {
  43.         //复用上面定义的重载运算符:> , ==
  44.         return *this > x || *this == x;
  45. }
  46. bool Date::operator!=(const Date& x) const
  47. {
  48.         //复用上面定义的重载运算符:==
  49.         return !(*this == x);
  50. }
复制代码
3.日期类的计算运算符重载

思路:
        对于日期类的计算运算符重载的界说,我们可以先界说 += 运算符重载和 -= 运算符重载,然后其他运算符重载的界说我们可以复用这两个运算符重载,从而实现各个运算符所要实现的目的。
代码实现:
  1. Date& Date::operator+=(int day)
  2. {
  3.         if (day < 0)
  4.         {
  5.                 return *this -= (-day);
  6.         }
  7.         _day = _day + day;
  8.         while (_day > Get_MonthDay(_year, _month))
  9.         {
  10.                 _day = _day-Get_MonthDay(_year, _month);
  11.                 ++_month;
  12.                 if (_month == 13)
  13.                 {
  14.                         _month = 1;
  15.                         ++_year;
  16.                 }
  17.         }
  18.         return *this;
  19. }
  20. Date Date::operator+(int day)const
  21. {
  22.         if (day < 0)
  23.         {
  24.                 return *this - (-day);
  25.         }
  26.         //复用上面定义的重载运算符:+=
  27.         Date tem(*this);
  28.         tem+= day;
  29.         return tem;
  30. }
  31. Date& Date::operator-=(int day)
  32. {
  33.         if (day < 0)
  34.         {
  35.                 return *this += (-day);
  36.         }
  37.         _day = _day - day;
  38.         while (_day < 1)
  39.         {
  40.                 --_month;
  41.                 if (_month <1 )
  42.                 {
  43.                         _month = 12;
  44.                         --_year;
  45.                 }
  46.                 _day = _day + Get_MonthDay(_year, _month);
  47.         }
  48.         return *this;
  49. }
  50. Date Date::operator-(int day)const
  51. {
  52.         if (day < 0)
  53.         {
  54.                 return *this + (-day);
  55.         }
  56.         //复用上面定义的重载运算符:-=
  57.         Date tem(*this);
  58.         tem -= day;
  59.         return tem;
  60. }
  61. Date& Date::operator++()
  62. {
  63.         //复用上面定义的重载运算符:+=
  64.         *this += 1;
  65.         return *this;
  66. }
  67. Date Date::operator++(int)
  68. {
  69.         //复用上面定义的重载运算符:+
  70.         Date tem = *this;
  71.         *this += 1;
  72.         return tem;
  73. }
  74. Date& Date::operator--()
  75. {
  76.         //复用上面定义的重载运算符:+=
  77.         *this -= 1;
  78.         return *this;
  79. }
  80. Date Date::operator--(int)
  81. {
  82.         //复用上面定义的重载运算符:+
  83.         Date tem = *this;
  84.         *this -= 1;
  85.         return tem;
  86. }
复制代码
        实现两个日期之间相减求天数时,我们可以先判定哪个日期大,从而确定出所求的天数是正数照旧负数,即用flage的正负来实现。接着我们界说一个n来统计天数,然后我们通过while循环,++最小的日期,而且++天数直到最小日期和最大日期相等的时候结束,这时候我们返回n*flage的值即是所求天数。
  1. int Date::operator-(const Date& x) const
  2. {
  3.         Date max = *this;
  4.         Date min = x;
  5.         int flage = 1;
  6.         if (*this < x)
  7.         {
  8.                 max = x;
  9.                 min = *this;
  10.                 flage = -1;
  11.         }
  12.         int n = 0;
  13.         while (min != max)
  14.         {
  15.                 ++min;
  16.                 ++n;
  17.         }
  18.         return n * flage;
  19. }
复制代码
4.流插入运算符重载。

思路:
        对于日期类利用系统中的流插入(只能插入内置类型)时并不能实现所期望的操作,因为日期类是自界说类型,所以我们就需要自己界说一个流插入来实现这个操作
  1.         // 流插入不能写成成员函数?
  2.         // 因为Date对象默认占用第一个参数,就是做了左操作数
  3.         // 写出来就一定是下面这样子,不符合使用习惯
  4.         //d1 << cout; // d1.operator<<(cout);
  5.         //void operator<<(ostream& out);
复制代码
因此,这里我们通过友元函数,在全局中界说流插入的运算符重载
代码实现:
  1. ostream& operator<<(ostream& out, const Date& x)
  2. {
  3.         out << x._year << "年" << x._month << "月" << x._day << "日" << endl;
  4.         return out;
  5. }
  6. istream& operator>>(istream& in, Date& x)
  7. {
  8.         int year, month, day;
  9.         in >> year >> month >> day;
  10.         if (month > 0 && month < 13
  11.                 && day > 0 && day <= x.Get_MonthDay(year, month))
  12.         {
  13.                 x._year = year;
  14.                 x._month = month;
  15.                 x._day = day;
  16.         }
  17.         else
  18.         {
  19.                 cout << "非法日期" << endl;
  20.                 assert(false);
  21.         }
  22.         return in;
  23. }
复制代码
3.源文件:Test.cpp

Test1:

用于检测日期类的比力运算符的重载
  1. void Test1()                //用于检测日期类的比较运算符的重载
  2. {
  3.         Date s1(2005, 2, 16);
  4.         Date s2(2024, 8, 12);
  5.         cout << "bool operator<(const Date& x) const:" << (s1 < s2) << endl;
  6.         cout << "bool operator==(const Date& x) const:" << (s1 == s2) << endl;
  7.         cout << "bool operator<=(const Date& x) const:" << (s1 <= s2) << endl;
  8.         cout << "bool operator>(const Date& x) const:" << (s1 > s2) << endl;
  9.         cout << "bool operator>=(const Date& x) const:" << (s1 >= s2) << endl;
  10.         cout << "bool operator!=(const Date& x) const:" << (s1 != s2) << endl;
  11. }
复制代码


Test2:

用于检测日期类的计算运算符的重载:+= , +
  1. void Test2()                //用于检测日期类的计算运算符的重载:+= , +
  2. {
  3.         Date s1(2005, 2, 16);
  4.         s1.Print();
  5.         s1 += 10000;
  6.         s1.Print();
  7.         Date s2(2005, 2, 16);
  8.         s2.Print();
  9.         Date s3=s2+10000;
  10.         s3.Print();
  11. }
复制代码


Test3:

用于检测日期类的计算运算符的重载:-= , -
  1. void Test3()                //用于检测日期类的计算运算符的重载:-= , -
  2. {
  3.         Date s1(2005, 2, 16);
  4.         s1.Print();
  5.         s1 -= 1000;
  6.         s1.Print();
  7.         Date s2(2005, 2, 16);
  8.         s2.Print();
  9.         Date s3 = s2 - 1000;
  10.         s3.Print();
  11. }
复制代码


Test4:

用于检测日期类的计算运算符的重载:--
  1. void Test4()                //用于检测日期类的计算运算符的重载:--
  2. {
  3.         Date s2(2005, 2, 16);
  4.         Date s3(2005, 2, 16);
  5.         Date s4;
  6.         s4=s2--;
  7.         s4.Print();
  8.         s4 = --s3;
  9.         s4.Print();
  10. }
复制代码


Test5:

用于检测日期类的计算运算符的重载:++
  1. void Test5()                //用于检测日期类的计算运算符的重载:++
  2. {
  3.         Date s2(2005, 2, 16);
  4.         Date s3(2005, 2, 16);
  5.         Date s4;
  6.         s4 = s2++;
  7.         s4.Print();
  8.         s4 = ++s3;
  9.         s4.Print();
  10. }
复制代码


Test6:

用于检测日期类之间的计算运算符的重载:-
  1. void Test6()                //用于检测日期类之间的计算运算符的重载:-
  2. {
  3.         Date s1(2005, 2, 16);
  4.         Date s2(2024, 8, 13);
  5.         cout << "int operator-(const Date& x) const:" << (s1 - s2) << endl;
  6. }
复制代码


Test7:

用于检测日期类之间的计算运算符的重载:<< , >>
  1. void Test7()                //用于检测日期类之间的计算运算符的重载:<< , >>
  2. {
  3.         Date s1;
  4.         cin >> s1;
  5.         cout << s1 << endl;
  6.         cout << s1 + 100 << endl;
  7. }
复制代码


四、结语:

         上述内容,即是我个人对C++日期类的个人见解及代码实现。若有大佬发现哪里有题目可以私信或评论指教一下。非常感谢各位uu们的点赞,关注,收藏,还望各位多多关照,让我们一起进步吧!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

温锦文欧普厨电及净水器总代理

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表