🔥个人主页:Quitecoder
🔥专栏:c++笔记仓
朋友们大家好啊,在我们学习了默认成员函数后,我们本节内容来完成知识的实践,来实现一个简易的日期计算器
目录
- 头文件声明函数
- 函数的实现
- 1.全缺省默认构造函数
- 2.拷贝构造函数
- 3.七个个运算符重载
- 4.日期计算函数
- 5.前后置加加减减
- 6.两个对象直接相减
头文件声明函数
头文件声明所有函数:
#pragma once
#include<iostream>using namespace std;class Date
{
public:int GetMonthDay(int year, int month){static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30,31 };int day = days[month];if (month == 2&& ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){day += 1;}return day;}// 全缺省的构造函数Date(int year = 1, int month = 1, int day = 1);// 拷贝构造函数// d2(d1)Date(const Date& d);// 赋值运算符重载// d2 = d3 -> d2.operator=(&d2, d3)Date& operator=(const Date& d);// 析构函数~Date();// 日期+=天数Date& operator+=(int day);// 日期+天数Date operator+(int day);// 日期-天数Date operator-(int day);// 日期-=天数Date& operator-=(int day);// 前置++Date& operator++();// 后置++Date operator++(int);// 后置--Date operator--(int);// 前置--Date& operator--();// >运算符重载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);// 日期-日期 返回天数int operator-(const Date& d);void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};
函数的实现
第一个函数,获取某月天数
class Date
{
public:int GetMonthDay(int year, int month){static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30,31 };int day = days[month];if (month == 2&& ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){day += 1;}return day;}
为了按照月的月份直接访问数组,我们设置大小为13,由于要进行多次访问,我们可以将数组变量设置在全局
如果是闰年,则二月为29天,返回某个月的天数
1.全缺省默认构造函数
Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
在头文件进行缺省,源文件不需要
2.拷贝构造函数
Date::Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}
3.七个个运算符重载
这里总共有七个运算符,除了赋值运算符外,我们只需要得到特殊的两个就可以简单的写出另外四个函数
首先,=
的重载
bool Date::operator==(const Date& d)
{return _year == d._year&& _month == d._month&& _day == d._day;
}
我们再写一个<
的重载
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;}}}return false;
}
按照年月日逐次判断
上面两个完成后,其余的就很简单了
小于等于,就是小于或者等于
bool Date::operator <= (const Date& d)
{return *this < d || *this == d;
}
直接使用小于和等于的重载
大于,即为不小于等于:
bool Date::operator>(const Date& d)
{return !(*this <= d);
}
大于等于,即为不小于
bool Date::operator >= (const Date& d)
{return !(*this < d);
}
最后一个不等于也十分简单了:
bool Date::operator != (const Date& d)
{return !(*this == d);
}
赋值运算符重载
Date& Date::operator=(const Date& d)
{if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;
}
4.日期计算函数
自身增加天数
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;if (_month == 13){++_year;_month = 1;}}return *this;
}
如果天数超过某个月,则天数减去当前这个月,让月份增加,如果月数等于13了,则年进一,月份重置为1月
有了加等,实现加就很简单了
Date Date::operator+(int day)
{Date tmp = *this;tmp += day;return tmp;
}
这两个有什么区别呢??
这两个函数都是Date
类的成员函数,用于对日期进行增加天数的操作,但它们在用法和效果上有所不同。
Date& Date::operator+=(int day)
这个函数重载了+=
运算符,允许你直接在当前对象上增加天数。它会修改调用它的对象本身,并返回修改后对象的引用。
特点:
- 直接修改:它修改调用对象的状态,即增加的天数直接反映在原对象上
- 返回引用:返回调用它的对象的引用,允许链式操作
用法示例:
Date d1(2020, 3, 30); // 假设是2020年3月30日
d1 += 3; // 在d1上增加3天
// d1现在是2020年4月2日
Date Date::operator+(int day)
这个函数重载了+
运算符,允许你在一个临时对象上增加天数,而不改变原始对象。它通过创建一个当前对象的副本,然后在这个副本上应用+=
操作,最后返回这个修改后的副本
特点:
- 不直接修改:它不会修改原始调用对象的状态,而是返回一个新的修改后的对象。
- 返回对象:返回一个新的
Date
对象,这个对象是在原对象基础上增加天数后的结果。
用法示例:
Date d2(2020, 3, 30); // 假设是2020年3月30日
Date d3 = d2 + 3; // 在d2的基础上增加3天,但d2本身不变
// d2仍然是2020年3月30日
// d3是2020年4月2日
operator+=
是一个修改原对象并返回其引用的成员函数,用于实现“就地修改”。operator+
是一个返回新对象的成员函数,它在不修改原对象的情况下返回增加天数后的新日期对象。
我们现在是加等嵌套在加里面,如果反过来呢?
对比我们能发现,两种加法都要创建一个新的变量,效果相同,但是加等,右边复用加的时候又创建对象,对比左边效率降低,所以用加复用加等效果更好
同理完成日期的减等和减
Date& Date::operator-=(int day)
{_day -= day;while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}
Date Date::operator-(int day)
{Date tmp = *this;tmp -= day;return tmp;
}
5.前后置加加减减
这里我们已经上篇文章讲解过了,直接进行代码的实现
Date& Date::operator++()
{_day += 1;return *this;
}
Date Date::operator++(int)
{Date tmp(*this);_day += 1;return tmp;
}
Date& Date::operator--()
{_day -= 1;return *this;
}
Date Date::operator--(int)
{Date tmp(*this);_day -= 1;return tmp;
}
6.两个对象直接相减
两个对象直接相减得到相差的日期天数:
int Date::operator-(const Date& d)
{int flag = 1;Date max = *this;Date min = d;if (*this < d){int flag = -1;max = d;min = *this;}int n = 0;while (min != max){++min;++n;}return n * flag;
}
这个实现逻辑首先确定哪个日期较大,然后不断将较小的日期递增,直到它与较大的日期相等,过程中累计递增的天数,最终返回这个天数。如果初始的第一个日期小于第二个日期,返回的天数会是负值
让我们分析一下代码的关键部分:
-
确定日期大小:代码首先比较两个日期,确保
max
总是较大的日期,而min
是较小的日期。flag
变量用于记录原始日期的相对顺序,如果需要反转(即第一个日期小于第二个日期),flag
会被设置为-1
-
计算天数差:通过一个循环,每次将
min
日期递增一天(使用operator++
),直到min
等于max
。每次递增都会将n
加1,n
用于记录两个日期之间相差的天数 -
返回结果:最后,返回累计的天数
n
乘以flag
。如果flag
为-1
,表示第一个日期实际上是小于第二个日期的,因此返回负值
本节内容到此结束,感谢大家阅读!