手把手教你实现日期类(上)

简介: 手把手教你实现日期类(上)

7d0da443b44a433fae8566250e94f4ff.png


前言

前面我们讲解了类的对象的大部分知识,例如拷贝构造,函数重载等知识,本节我们将用所学的知识对日期类进行实现。

注意:本篇博客代码的实现综合了前面所学,同时可能会捎带一点点后面所学内容。

1.头文件的实现

定义日期的类,对公共部分的函数进行声明,私有成员的确定。

函数有日期输入输出,日期判断,日期的大小比较,日期增减。

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
class Date {
  friend ostream& operator<<(ostream& out, const Date&d);
  friend istream& operator>>(istream& in, Date& d);
public:
  Date(int year = 1, int month = 1, int day = 1);
  void Print();
  int Getday(int year, int month) const{
    assert(month > 0 && month < 13);
    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;
    }
    else
      return monthDayArray[month];
  }
 
  bool CheckDate();
  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;
  // d1 += 天数
  Date& operator+=(int day);
  Date operator+(int day) const;
  // d1 -= 天数
  Date& operator-=(int day);
  Date operator-(int day) const;
  // d1 - d2
  int operator-(const Date& d) const;
  
  // ++d1 -> d1.operator++()
  Date& operator++();
  
  // d1++ -> d1.operator++(0)
  // 为了区分,构成重载,给后置++,强⾏增加了⼀个int形参
  // 这⾥不需要写形参名,因为接收值是多少不重要,也不需要⽤
  // 这个参数仅仅是为了跟前置++构成重载区分
  Date operator++(int);
  Date& operator--();
  Date operator--(int);
  // 流插⼊,流输入输出
  // 不建议,因为Date* this占据了⼀个参数位置,使⽤d<<cout不符合习惯
   //void operator<<(ostream& out);
 
private:
  int _year;
  int _month;
  int _day;
};
ostream& operator<<(ostream& out, const Date&d);
istream& operator>>(istream& in, Date& d);

在这里,我们用了一个数组来存取各月份的天数,避免连续用多个if else选择语句使代码冗杂,痛过闰年判断来进一步决定二月份的天数。

这个获取月份天数我们要频繁调用,所以我们直接定义在类里面,默认内联函数,频繁调用。

2.日期类函数各项功能实现

因为是在.cpp文件,在我们定义的头文件Date类以外,所以类外声明我们要用到 ::  操作符。

即Date::

2.1 初始化和打印(比较简单)

bool Date::CheckDate() {
  if (_month < 1 || _month > 12
    || _day < 1 || _day > Getday(_year, _month))
  {
    return false;
  }
  else
  {
    return true;
  }
}
Date::Date(int year, int month, int day)
{
  _year = year;
  _month = month;
  _day = day;
  if (!CheckDate())
  {
    cout << "⽇期⾮法" << endl;
  }
}
void Date::Print(){
  cout << _year << "-" << _month << "-" << _day << endl;
}

这里我们写了个检查日期函数,为了方便判断我们所给定的日期是否是非法的,也使日期类函数功能更加完善。

2.2日期大小判断

判断日期大小,从年月日依次判断,通过代码发现,只要实现了基本的等于和大小判断,其他的判断实现我们都可以用过逻辑运算形式来实现。这样可以减少代码量。

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;
    else
      return false;
  }
  else
    return false;
}
bool Date::operator<=(const Date& d) const {
  return *this < d || *this == d;
}
/*
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;
    else
      return false;
  }
  else
    return false;
}
*/
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 _year == d._year && _month==d._month&&_day==d._day;
}
bool Date::operator!=(const Date& d) const
{
  return !(*this == d);
}

2.3日期的加减运算

对于加减运算看起来简单,思路也挺丰富,但是通过代码实现还是有一定的难度的,接下来小编带领大家分析实现。

日期加天数

对于日期加天数,我们要进位并且还要判断是否满年和满该月,然后向前加

Date& Date::operator+=(int day) {
  if (day < 0) {
    return *this -= (-day);
  }
    _day += day; // 将传入的天数加到当前日期的天数上
  while (_day > (Getday(_year, _month))) { // 检查当前日期是否超过了这个月的天数
    _day -= Getday(_year, _month); // 减去这个月的天数
    _month++; // 月份加一
    if (_month == 13) { // 如果月份超过 12
      _month = 1; // 重置为 1
      _year++; // 年份加一
    }
  }
  return *this; // 返回当前对象的引用
}

这里的返回是传引用返回,在原来的日期上进行修改,更好的支持链式操作,当然我们也可以通过传值返回,只不过要拷贝一份,加临时变量。

为了方便区分理解,传引用我们定义为+=,传值为+

传值调用法可以借鉴+=的思路,创建一个临时变量temp,在所有成员前面加temp.即可

Date Date::operator+(int day) const{
  Date temp = *this;
  temp._day += day;
  while (temp._day > (Getday(temp._year, temp._month))) {
    temp._day -= Getday(temp._year,temp. _month);
    temp._month++;
    if (temp._month == 13) {
      temp._month = 1;
      temp._year++;
    }
 
  }
  return temp;
}

当然一个简便的方法是临时生成一个temp,通过+=函数改变temp,再返回temp。

Date Date::operator+(int day)const {
  Date temp = *this;
  temp += day;
  return temp;
}

日期减天数

我们要采取借位的方法,通过用上一个月份的天数加到_day上,直到>0为止。

Date& Date::operator-=(int day) {
    if (day < 0) {
  return *this += (-day);
}
    _day -= day; // 从当前日期的天数中减去传入的天数
    while (_day <= 0) { // 检查当前日期的天数是否小于或等于0
        _month--; // 减少月份
        if (_month == 0) { // 如果月份变为0,意味着需要回到上一年
            _month = 12; // 将月份重置为12
            _year--; // 年份减少
        }
        _day += Getday(_year, _month); // 为当前月份添加天数
    }
    return *this; // 返回当前对象的引用,
}


手把手教你实现日期类(下):https://developer.aliyun.com/article/1624944

目录
相关文章
|
9天前
|
存储 C++
【C++篇】C++类和对象实践篇——从零带你实现日期类的超详细指南
【C++篇】C++类和对象实践篇——从零带你实现日期类的超详细指南
17 2
【C++篇】C++类和对象实践篇——从零带你实现日期类的超详细指南
|
1天前
|
C++
手把手教你实现日期类(下)
手把手教你实现日期类(下)
3 0
|
8天前
|
C++
C++番外篇——日期类的实现
C++番外篇——日期类的实现
36 1
|
2月前
|
编译器 C++
【CPP】手把手教会日期类,日期类实现思路,详细思路
【CPP】手把手教会日期类,日期类实现思路,详细思路
|
5月前
|
编译器 C++
『C++成长记』日期类的实现
『C++成长记』日期类的实现
|
5月前
|
C语言 C++ 容器
[C++从入门到精通] 3.string类型的相关用法
[C++从入门到精通] 3.string类型的相关用法
61 0
[C++从入门到精通] 3.string类型的相关用法
|
5月前
|
C语言
c语言编程练习题:7-12 日期格式化
世界上不同国家有不同的写日期的习惯。比如美国人习惯写成“月-日-年”,而中国人习惯写成“年-月-日”。下面请你写个程序,自动把读入的美国格式的日期改写成中国习惯的日期。
188 0
日期类相关练习题
日期类相关练习题
69 0
|
C++
【C++基础】实现日期类
【C++基础】实现日期类
58 0