目录:
- Date.h实现函数声明
- Date.c实现函数功能
- 构造函数
- 六个比较函数
- 日期 + 天数
- 日期 - 天数
- 日期 - 日期
- 操作符
++
- 操作符
--
- 获取每月的天数
🚘正片开始
Date.h头文件中实现函数声明
#pragma once
#include<iostream>
using namespace std;
class Date
{friend istream& operator>>(istream& in, Date& d);public://构造函数Date(size_t year = 1970, size_t month = 1, size_t day = 1);//打印数据void Print_Date();//日期的比较bool operator<(const Date& d);bool operator<=(const Date& d);bool operator>(const Date& d);bool operator>=(const Date& d);bool operator==(const Date& d);bool operator!=(const Date& d);//日期加天数Date operator+(int day);Date& operator+=(int day);//日期减天数Date operator-(int day);Date& operator-=(int day);//日期减日期int operator-(Date& d);//前置++Date& operator++();//后置++Date operator++(int);//日期--//前置--Date& operator--();//后置--Date operator--(int);//每月多少天(因为此函数会经常使用所以定义在类中,为内敛函数)int Month_Day(size_t year, size_t month){static int DayArr[13] = { 0,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;}return DayArr[month];}private:size_t _year;size_t _month;size_t _day;
};
构造函数
此构造函数为全缺省Date::Date(size_t year, size_t month, size_t day)
{_year = year;_month = month;_day = day;
}
注意:此处是头文件和源文件分开写的,所以函数声明只需在头文件声明即可
六个比较函数
在这七个比较函数中,只需要先写 <
和 ==
其他比较函数直接进行复用即可轻松解决。
重载小于函数
bool Date::operator<(Date d)
{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;}}return false;
}
这里的小于函数实现原理是:
如果
*this
年小就返回true
,*this
年等就判断月,如果*this
月小就返回true
,*this
月等就判断天数,如果*this
的天数小则返回true
否则其他情况一律返回false
- 重载
==
函数
bool Date::operator==(Date d)
{return (_year==d._year)&&(_month==d._month)&&(_day==d._day);
}
下面的比较函数直接可以复用上面的两个函数使其实现函数难度大大降低,是一种非常巧妙的写法
- 重载
<=
函数
bool Date::operator<=(Date d)
{return (*this)<d || (*this)==d;
}
实现 <=
无非就是 <
或 ==
的其中一种情况 只需用一个或运算符连接即可完成此函数
- 重载
>
函数
bool Date::operator>(Date d)
{return !((*this) <= d);
}
实现 >
无非就是 <=
的反面 所以只需要对 <=
函数取反即可完成此函数
- 重载
>=
函数
bool Date::operator>=(Date d)
{return !((*this) < d);
}
实现 >=
无非就是 <
的反面 所以只需要对 <
函数取反即可完成此函数
- 重载
!=
函数
bool Date::operator!=(Date d)
{return !((*this)==d);
}
实现 !=
无非就是 ==
的反面 所以只需要对 ==
函数取反即可完成此函数
日期 - 天数
- 日期+天数
Date Date::operator+(int day)
{Date tmp(*this);if (day < 0){tmp -= (-day);}else{tmp += day;}return tmp;
}
函数里面的if语句是为了避免day为负数的情况,如果为负数则变成了 d-天数
原本应该是 d+天数
的为了让他传负数也能实现,我们复用了 -=
函数重载
- 日期+=天数
Date& Date::operator+=(int day)
{//为了避免day为负数造成*this-=day,所以我们复用了-=函数重载让它依旧可以实现相应的功能if (day < 0){*this -= (- day);return *this;}_day += day;while (_day > Month_Day(_year, _month)){_day -= Month_Day(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}}
日期 - 天数
- 日期 - 天数
Date Date::operator-(int day)
{Date tmp(*this);if (day < 0){tmp += (-day);}else{tmp -= day;}return tmp;
}
小知识点:因为tmp为临时变量出了函数会被销毁,通常我们函数返回值会避免拷贝的发生通常使用引用返回,但是在这个地方无法使用引用是因为tmp为临时变量
- 日期 -= 天数
void Date::operator-=(int day)
{if (day < 0){*this += (-day);return;}_day -= day;while (_day <= 0){_month--;if (_month == 0){_year--;_month = 12;}_day += Month_Day(_year, _month);}
}
日期 - 日期
//假设是*this-d;
int Date::operator-(Date& d)
{//先假设*this>dDate max = *this;Date min = d;int count = 0;int flag = 1;//如果不是*this>dif (*this < d){max = d;min = *this;flag = -1;}while (min < max){++min;++count;}return count*flag;
}
操作符 ++
- 前置
++
Date& Date::operator++()
{*this += 1;return *this;
}
- 后置
++
Date Date::operator++(int)
{Date tmp(*this);*this += 1;return tmp;
}
由于 前置++ 和 后置++ 在函数上无法区别,所以c++创始人规定后置++ 函数括号内必须带一个 int 类型来进行区分,其实也可以把 前置++ 函数 和 后置++ 函数 理解为是运算符重载
操作符 --
- 前置
--
Date& Date::operator--()
{*this -= 1;return *this;
}
- 后置
--
Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}
获取每月的天数
int Month_Day(size_t year, size_t month)
{//每月的天数static int DayArr[13] = { 0,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;}return DayArr[month];
}
单独把这个函数拿出来是因为此函数比较特别,因为这函数会经常使用所以定义在类中,为内敛函数。
大家可能对内敛函数比较陌生在此我给大家讲解一下内敛的好处👇
在一个类中定义的函数会被默认为内敛函数,前提是此函数代码量不多,因为大家都知道函数被调用的时候会建立栈帧,会消耗一定的空间和时间,如果编译器识别这个函数为内敛函数,编译器会自动展开函数,不调用函数栈帧 ,从而降低了时间和空间的消耗
接下来我们来讲讲获取天数的函数中的一些小细节
数组用static修饰是为了不让数组多次创建造成效率的浪费,定义13个元素是为了月份对应上下标
总结:本章主要是对运算符重载的应用,写个日期类的项目加强我们对知识点的记忆,本章也涉及到了一些小细节,需要细细斟酌,才能领悟,加油铁子们!!!
🎉🎉🎉完结