c++仙阁 类和对象 他化万古 日期类 原创
春节不停更,此文正在参加「星光计划-春节更帖活动」https://harmonyos.51cto.com/posts/9923
日期类
我们要有一个习惯就是写代码或者是写项目的时候我们要==写一点编一点==,要养成良好的习惯,万万不可以写完了再编,然后出了一堆错误自己都不想看,我们先自己编个最小项目或者系统框架在加其他功能
Date.h
Date.h
就是一些头文件,声明啥的#pragma once #include <iostream> using std::cout; using std::cin; using std::endl; class Date { public: Date(int year = 0, int month = 1, int day = 1); void Print(); //像析构,拷贝构造,赋值重载可以不需要写,因为默认生成的就够用了, //像Stack才需要自己写这三个 //日期加 减天数 Date operator+(const int& day); Date operator-(const int& day); private: int _year; int _month; int _day; };
Date.cpp
Date.cpp
这里面就是写日期类的函数了#include "Date.h" Date::Date(int year, int month, int day) { _year = year; _month = month; _day = day; } void Date::Print() { cout << _year << "年" << _month << "月" << _day << "日" << endl; } Date Date::operator+(const int& day) { return *this; } Date Date::operator-(const int& day) { return *this; }
test.cpp
test.cpp
#include "Date.h" int main() { Date d(2022,1,1); d.Print(); return 0; }
测试情况
功能添加
当我们能基本丐版跑出来了那我们接下来的路还是要走的,我们要考虑到数据是否合理啊什么的
==所以我们需要检查日期的合法性==
==上面的确是排除了百分之99的滤掉了,但是闰年2月是特殊考虑的反而没有代码实现==
==我们可不可以优化一下,比如我就输错了一个日期你就直接程序死了是不是有点太霸道了,你应该抛出异常,或隔一下啥的==
inline int GetMonthDay(int year, int month) { //数组存放平年每个月的天数 刚好对应的下标是月 里面的元素是天 static int dayArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; //该月天数 int day = dayArray[month]; //闰年是4年一润百年不润或者四百年一润 if (month == 2 && (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { //闰年的2月是29天 day = 29; } return day; } Date::Date(int year, int month, int day) { //检查日期的合法性 if (year > 0 && month > 0 && month <13 && day > 0 && day <= GetMonthDay(year,month)) { _year = year; _month = month; _day = day; } else { cout << endl; cout << "非法日期" << endl; cout << year << "年" << month << "月" << day << "日" << endl; } } void Date::Print() { cout << _year << "年" << _month << "月" << _day << "日" << endl; }
日期加天数后那个日期
Date& Date::operator+=(const int& day) { //我们先不管,我们先直接把天加上去 _day += day; //然后再判断合不合法 while (_day > GetMonthDay(_year,_month)) { //先把当月的天数减掉 _day -= GetMonthDay(_year, _month); //然后月++ _month++; //假如月也过了就年++ if (_month > 12) { _year++; _month = 1; } } return *this; }
日期加天数
==仅仅就是加没有赋值过去,要和上面那个分清了,所以我需要一个中间临时变量(这个我们叫临时对象)来存储运算后的数据==
//日期加天数 不赋回去 Date Date::operator+(const int& day) { //首先创建一个临时对象 先把之前的拷贝复制给他 Date ret(*this); //复用+= ret += day; return ret; }
日期++,++日期
==日期加加和加加日期都是++,但是operator运算符重载怎么区分呢,==
前置++
==前置++返回运算以后的值==
//++d 日期前置++ 被转换成d.operator++(&d) Date& Date::operator++() { //返回运算后的值 *this += 1; return *this; }
后置++
==后置++返回运算前的值==
//d++ 日期后置++ 被转换成d.operator++(&d,0) //这里的int仅仅是占位,不需要给实参,起到函数重载的作用 Date& Date::operator++(int) { //后置++返回运算前的值 //所以需要一个临时对象先存起来 Date tmp(*this); *this += 1; return tmp; }
日期减天数后那个日期
//日期减天数同时赋回去 Date& Date::operator-=(const int& day) { //啥也不多说,先把天减掉 _day -= day; //不合法就等他合法 while (_day <= 0) { //先把月减了 _month--; //先判断月是不是零,是的话就操作年了 if (_month <= 0) { _year--; _month = 12; } //然后让他加上正确的月的天数 _day += GetMonthDay(_year,_month); } return *this; }
日期减天数
==复用上面那个函数就行==
//日期减天数 不赋回去 Date Date::operator-(const int& day) { Date ret(*this); //-=的复用 ret -= day; return ret; }
日期–,–日期
==日期减减和减减日期都是–,但是operator运算符重载怎么区分呢,==
前置–
==前置–返回运算以后的值==
//前置减减 Date& Date::operator--() { *this -= 1; return *this; }
后置–
==后置–返回运算前的值==
//后置减减 Date& Date::operator--(int) { Date tmp(*this); *this -= 1; return tmp; }
修一修bug
若是-=里面的日期是负数的话
==我们有时候是需要考虑日期里面是有负数的==
==所以需要我们改一下代码,需要+=的代码,直接挪用==
==复用即可==
//日期减天数同时赋回去 Date& Date::operator-=(const int& day) { //每月天数超过他本身了也是违法的 //复用+=即可 if (day < 0) { *this += -day; } else { //啥也不多说,先把天减掉 _day -= day; //不合法就等他合法 while (_day <= 0) { //先把月减了 _month--; //先判断月是不是零,是的话就操作年了 if (_month <= 0) { _year--; _month = 12; } //然后让他加上正确的月的天数 _day += GetMonthDay(_year, _month); } } return *this; }
若是+=里面的日期是负数的话
==同样的+=里面有负数也是一样的处理==
==所以我们也把-=的代码拎过来==
==同理复用即可==
//日期加天数同时赋回去 Date& Date::operator+=(const int& day) { //负数复用-=的 if (day < 0) { *this -= -day; } else { //我们先不管,我们先直接把天加上去 _day += day; //然后再判断合不合法 while (_day > GetMonthDay(_year, _month)) { //先把当月的天数减掉 _day -= GetMonthDay(_year, _month); //然后月++ _month++; //假如月也过了就年++ if (_month > 12) { _year++; _month = 1; } } } return *this; }
比较运算符
大于 >
==d1 > d2==
//比较 //大于 d1 > d2转换成d1.operator>(&d1,d2) bool Date::operator>(const Date& d) { if (_year > d._year) { return true; } else if (_year == d._year) { if (_month > d._month) { return true; } else if(_month == d._month) { if (_day > d._day) return true; } } //不是上面情况就false return false; }
等于 ==
==d1 == d2==
//等于 bool Date::operator==(const Date& d) { return _year == d._year && _month == d._month && _day == d._day; }
大于等于 >=
==d1 >= d2==
//大于等于 bool Date::operator>=(const Date& d) { return *this > d || *this == d; }
小于<
==d1 < d2==
//小于 bool Date::operator<(const Date& d) { return !(*this >= d); }
小于等于 <=
==d1 <= d2==
//小于等于 bool Date::operator<=(const Date& d) { return !(*this > d); }
不等于 !=
==d1 != d2==
//不等于 bool Date::operator!=(const Date& d) { return !(*this == d); }
生活实际
我们思考一个问题就是日期减日期有没有意义
日期减日期是不是就是相差多少天,那你这个怎么操作呢
//日期减日期 //通过计数的方式来 要是年减年 月减月就是无法找到实际多少天了 int Date::operator-(const Date& d) { //首先假设前面的大 Date max = *this; //所以后面的就小 Date min = d; //符号标记 int flag = 1; //如果错了就交换 if (max < min) { max = d; min = *this; flag = -1; } //当min与max相同时就是停止计数的时候 int count = 0; while (min != max) { min++; count++; } //出来就把计数返回出去顺带着标记 return count * flag; }