文章目录
前言
本文总结学习日期类(c++实现)。
一、日期类头文件Date.h
本节主要包含:类的创建,部分成员函数声明,部分成员函数定义,成员变量的声明,头文件包含
#pragma once
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
class Date
{
public:
// 判断闰年
bool Isleapyear(int year)
{
if ((0 == year % 4 && 0 != year % 100) || (0 == year % 400))
{
return true;
}
return false;
}
// 获取该月的天数
size_t GetMonthDay(int year, int month)
{
// 2月的天数先默认取为平年的28天
int MonthDay[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (2 == month && Isleapyear(year))
{
MonthDay[2]++;
}
return MonthDay[month];
}
// 构造函数需自己写(成员变量全为内置类型,编译器默认生成的默认构造函数对内置类型不处理)
// 1-初始化列表初始化,这样无法判断非法日期
/*Date(int year, int month, int day)
:_year(year)
,_month(month)
,_day(day)
{}*/
// 2-构造函数初始化
Date(int year = 1, int month = 1, int day = 1)// 这里写为构造函数或者默认构造函数(不用传参就可以调用)都可以
{
// 判断日期的合法性
if (year >= 1 && month >= 1 && month <= 12 && day >= 1 && day <= GetMonthDay(year, month))
{
this->_year = year;
this->_month = month;
this->_day = day;
}
else
{
cout << "日期非法" << endl;
}
}
// 析构函数无须自己写(成员变量均为内置类型,无须资源清理,编译器默认生成的默认析构函数足以)
// 拷贝构造函数无需自己写(成员变量均为内置类型,无须深拷贝,编译器默认生成的默认拷贝构造函数足以)
// 打印
void Print()const// this指向的对象无须修改,加const
{
cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
}
// 赋值运算符重载,日期=日期
const Date& operator=(const Date& d);
// 日期+=天数
Date& operator+=(int day);
// 日期+天数
Date operator+(int day)const;
// 日期-=天数
Date& operator-=(int day);
// 日期-天数 同上
// ++日期
Date& operator++();
// 日期++
Date operator++(int);
// ++日期
// 日期-- 同上
// 日期>日期?
bool operator>(const Date& d)const;
// 日期==日期?
bool operator==(const Date& d)const;
// 日期>=日期?
bool operator>=(const Date& d)const;
// 日期!=日期?
bool operator!=(const Date& d)const;
// 日期<日期 日期<=日期 同上
// 日期-日期
int operator-(const Date& d)const;
// 流提取操作符
friend std::ostream& operator<<(std::ostream& out, const Date& d);// 不太理解!!!!!!!!!!!!!
// 流插入操作符
friend std::istream& operator>>(std::istream& in, Date& d);// 不太理解!!!!!!!!!!!!!
private:
// 成员变量
int _year;
int _month;
int _day;
};
二、日期类成员函数具体实现Date.c
本节主要包含:部分成员函数的定义
2.1 日期=日期
// 赋值运算符重载,d2 = d1 -> d2.operator(d1) -> d2.operator(&d2, d1)
// this指向的对象需要改,不加const
// 相当于const Date& opeator=(Date* const this,const Date& d1),d不修改所以加const
const Date& Date::operator=(const Date& d)
{
// 判定不是自我赋值
if (this != &d)
{
this->_year = d._year;
this->_month = d._month;
this->_day = d._day;
}
return *this;
}
2.2 日期+=天数
// 日期+=天数,d2 += 1 -> d2.operator(1) -> d2.operator(&d2, 1)
// this指向的对象需要改,不加const
// 相当于Date& operator+=(Date* const this, int day)
// 返回类型不用const Date&,因为定义对象如果不是const对象,接收会使得权限缩小
Date& Date::operator+=(int day) // 返回值改为void也可以?返回值有什么用???????????????应该是为了连续赋值
{
// 先构造临时对象,确保原本的天数加上新天数后合法 想错,因为没有合法一说,多出来的天数进制!!!!!!!!!
_day += day;
// 多出来的天数进制!!!!!!!!!!!!!
while (_day > GetMonthDay(_year, _month))
{
// 向前进一个月
_day -= GetMonthDay(_year, _month);
_month++;
// 月份超出12
if (_month > 12)
{
_year++;
_month = 1;
}
}
// 返回引用类型时,引用的对象必须出了作用域仍然存在!!!!!!!!!!
return *this;
}
2.3 日期+天数
// 日期+天数,d2 = d1 + 2 -> d1.operator(2) -> d1.operator(&d1, 2)
// this指向的对象不用修改,加const
// 相当于Date operator+(const Date* const this, int day)
// 返回值不用引用,因为+计算后d1的值不变,返回值用引用只能引用出作用域还存在的对象,此处不是返回d1,而是计算后的新对象
Date Date::operator+(int day)const
{
// 先构造临时对象,确保原本的天数加上新天数后合法
Date tmp(*this);
tmp._day += day;
// 多出来的天数进制!!!!!!!!!!!!!!
while (tmp._day > tmp.GetMonthDay(tmp._year, tmp._month))
{
// 向前进一个月
tmp._day -= tmp.GetMonthDay(tmp._year, tmp._month);
tmp._month++;
// 月份超出12
if (tmp._month > 12)
{
tmp._year++;
tmp._month = 1;
}
}
return tmp;
}
// +和+=复用时:
// 1:+复用+=:(2次拷贝构造 -> 2次拷贝构造)相对更优
// Date tmp(*this);
// tmp += day;
// return tmp;
// 2:+=复用+时:(0次拷贝构造 -> 2次拷贝构造)
// *this = *this + day
// return *this
2.4 日期-=天数
// 日期-=天数
Date& Date::operator-=(int day)
{
// 负数也可以处理!!!!!!!!!!!!!!!!!
if (day < 0)
{
return *this += (-day);
}
this->_day -= day;
while (this->_day <= 0)
{
// 天数重置,相应月份也改变
this->_day += this->GetMonthDay(this->_year, this->_month - 1);
this->_month--;
if (0 == this->_month)
{
this->_month = 12;
this->_year--;
}
}
return *this;
}
2.5 ++日期
// ++日期,++d1 -> d1.operator++() -> d1.operator++(&d1)
// this指向的对象修改,不加const
// 相当于Date operator++(Date* const this)
// 返回值用引用,返回值用引用只能引用出作用域还存在的对象,此处返回*this即d1
Date& Date::operator++()
{
(*this) += 1;// 合法性在+=运算符重载中确定
return *this;
}
2.6 日期++
// 日期++,d1++ -> d1.operator++(int) -> d1.operator++(int, &d1)
// this指向的对象修改加const
// 相当于Date operator++(int, const Date* const this)
// 返回值不用引用,返回值用引用只能引用出作用域还存在的对象,此处返回(*this+1),在+运算符重载中返回的是新对象
Date Date::operator++(int)
{
//return ((*this) + 1);// 合法性在+运算符重载中确定 理解错,后置++是赋值原先的值,但是自身改变!!!!!!!!
Date tmp(*this);
*this += 1;
return tmp;
}
2.7 日期>日期
// 日期>日期?,d1>d2 -> d1.operator>(d2) -> d1.operator>(&d1, d2)
// this指向的对象不修改加const
// 相当于bool operator>(const Date* const this, const Date& d)const,d不修改所以加const
// 返回bool值
bool Date::operator>(const Date& d)const
{
// 已创建的对象,需经过构造函数判定日期合法,所以已存在的对象比较,日期必合法
/*if (this->_year > d._year)
{
return true;
}
if (this->_year == d._year && this->_month > d._month)
{
return true;
}
if (this->_year == d._year && this->_month == d._month && this->_day > d._day)
{
return true;
}*/
// 可合并!!!!!!!!!!!!!!!!
if ((_year > d._year)
|| (_year == d._year && _month > d._month)
|| (_year == d._year && _month == d._month && d._day > d._day))
{
return true;
}
// 上述代码执行完之后始终没有返回则返回false
return false;
}
2.8 日期==日期
// 日期==日期?,d1==d2 -> d1.operator==(d2) -> d1.operator==(&d1, d2)
// this指向的对象不修改加const
// 相当于bool operator==(const Date* const this, const Date& d)const,d不修改所以加const
// 返回bool值
bool Date::operator==(const Date& d)const
{
// 已创建的对象,需经过构造函数判定日期合法,所以已存在的对象比较,日期必合法
return (this->_year == d._year && this->_month == d._month && this->_day == d._day);
}
2.9 日期>=日期
// 日期>=日期?,d1>=d2 -> d1.operator>=(d2) -> d1.operator>=(&d1, d2)
// this指向的对象不修改加const
// 相当于bool operator>=(const Date* const this, const Date& d)const,d不修改所以加const
// 返回bool值
bool Date::operator>=(const Date& d)const
{
// 已创建的对象,需经过构造函数判定日期合法,所以已存在的对象比较,日期必合法
return ((*this > d) || (*this == d));
}
2.10 日期!=日期
// 日期!=日期?,d1!=d2 -> d1.operator!=(d2) -> d1.operator!=(&d1, d2)
// this指向的对象不修改加const
// 相当于bool operator!=(const Date* const this, const Date& d)const,d不修改所以加const
// 返回bool值
bool Date::operator!=(const Date& d)const
{
return !(*this == d);
}
2.11 日期-日期
// 日期-日期,d1-d2 -> d1.operator(d2) -> d1.operator(&d1, d2)
// this指向的对象不修改加const
// 相当于int operator-(const Date* const this, const Date& d)const,d不修改所以加const
// 返回int值
int Date::operator-(const Date& d)const// 不会!!!!!!!!!!!!!!!!!!!!
{
// 看了解析后写:
Date max = *this;
Date min = d;
int index = 1;
if (d > *this)
{
max = d;
min = *this;
index = -1;
}
int ret = 0;
while (max != min)
{
++ret;
++min;
}
return ret * index;
}
2.12 流插入运算符重载(全局函数)
// 流插入操作符重载(全局函数)
std::istream& operator>>(std::istream& in, Date& d)//要改变d的成员,所有不加const
{
// 判断日期的合法性
if (d._year >= 1 && d._month >= 1 && d._month <= 12 && d._day >= 1 && d._day <= d.GetMonthDay(d._year, d._month))
{
in >> d._year >> d._month >> d._day;
return in;
}
else
{
cout << "日期非法" << endl;
}
}
2.13 流提取运算符重载(全局函数)
// 流提取操作符重载(全局函数)
std::ostream& operator<<(std::ostream& out, const Date& d)
{
out << d._year << "-" << d._month << "-" << d._day << endl;
return out;
}
总结
这里对文章进行总结:
以上就是今天总结的内容,本文包括了类与对象-日期类(c++实现),分享给大家。
真💙欢迎各位给予我更好的建议,欢迎访问!!!小编创作不易,觉得有用可以一键三连哦,感谢大家。peace
希望大家一起坚持学习,共同进步。梦想一旦被付诸行动,就会变得神圣。
欢迎各位大佬批评建议,分享更好的方法!!!🙊🙊🙊