日期类的实现_r6-3 日期类的设计与实现使用重载运算符(++,+=,<<等)实现日期类的操作。功能包括 (1)

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

{

return !(*this <= d);

}


### 1.5 ‘>=’重载


#### 声明



// >=运算符重载
inline bool operator >= (const Date& d);

####  定义


直接复用 > 和 == :



bool Date::operator >= (const Date& d)
{

return *this > d || *this == d;

}


或者复用 < :



bool Date::operator >= (const Date& d)
{

return !(*this < d);

}


###  1.6 ‘!=’重载


#### 声明



// !=运算符重载
bool operator != (const Date& d);

####  定义


复用 == ,取反即可:



bool Date::operator != (const Date& d)
{

return !(*this == d);

}


## 2. 赋值 ‘=’重载


#### 声明



// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& operator=(const Date& d);

#### 定义


返回的就是Date类型,就好比有两个整型变量: a=b ,返回的类型也是整型



> 
> **为什么要加引用呢?**
> 
> 
> 
> **a.this指针出了函数作用域会销毁,但是this所指向的内容是不会销毁的,因此我们可以考虑使用引用返回**
> 
> 
> 
> **b. 并且如果不用引用返回,同类型的对象传值传参会调用拷贝构造,减少开销,也推荐使用引用返回**
> 
> 
> 



Date& Date::operator=(const Date& d)
{
if (*this != d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}


## 3. 对日期天数进行计算


对日期进行计算:


比如加上天数减去天数,会涉及到月份或年的增加或减少问题。这里就需要判断天数是否超过当前对应月份天数的限制,月份是否超过12等等。并且对于特殊的2月,我们还需区分闰年和平年。


### 确定月份天数


#### 声明


最后返回的是天数



int GetMonthDay(int year, int month);

#### 定义



//Leapyear(year) 是bool类型,判断是否是闰年

int Date::GetMonthDay(int year, int month)
{

在这里对年和月份进行判定
assert(year >= 0 && month>0 && month<13);

static int MDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month == 2 && Leapyear(year))
{
	return 29;
}
else
{
	return MDay[month];
}

}



> 
> **这里要注意为什么在数组前加上 static ,不加也是可以的,但是每次创建时调用此函数,都会开辟出新数组,static 可以保持此数组只初始化一次,使用时再次调用即可,可降低开销,提高效率。**
> 
> 
> 


### 判断是否是闰年


#### 定义


我们直接将此函数在类中定义,将默认他是内联函数: 



bool Leapyear(int year)
{
	if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
	{
		return true;
	}
	else
	{
		return false;
	}
}

### 3.1 日期加天数 ‘+’的重载


#### 声明



// 日期+天数
Date operator+(int day);

####  定义



> 
> 这里首先要用到拷贝构造,创建一个临时的日期类,对临时的进行更改,最后返回,就比如 a+3后,a 是不改变的。a = a+3,a才会改变。这里的运算相当于a+3
> 
> 
> 
> 要考虑天数过大时,边界问题,天数有边界,月份有边界,超过月份的天数限制,月份+1,月份==13时,年+1
> 
> 
> 按照此逻辑进项实现:
> 
> 
> 



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


#### 小拓展



> 
> **当一个对象取初始化另一个不存在的对象时,调用的是构造拷贝**
> 
> 
> **只有两个存在的对象使用=时,才是赋值**
> 
> 
> ![](https://img-blog.csdnimg.cn/1f288966c61c4dc18db0eca5877da722.png)
> 
> 
>  ![](https://img-blog.csdnimg.cn/900633a72be740a69fe2907455be42cc.png)
> 
> 
> 
> 


### 3.2 日期加天数 ‘+=’的重载


相当于 a=a+b ,a本身会改变


#### 声明



// 日期+=天数
Date& operator+=(int day);

#### 定义



> 
> **和+的逻辑相同,只不过是直接修改 this 指向的内容,注意这里的返回值与 + 不同,+ 返回的是临时变量,用传值,而这里this会销毁,  \*this 不会销毁,直接返回 \*this即可,返回它本身用引用返回。**
> 
> 
> 
> **判断day为负的情况,复用 -=**
> 
> 
> **+=负值等价于-=正值:**
> 
> 
> 



Date& Date::operator+=(int day)
{
if (day<0)
{
return *this -= -day;
}

_day += day;
while (_day>GetMonthDay(_year, _month))
{
	_day -= GetMonthDay(_year, _month);
	_month++;
	if (_month == 13)
	{
		_year++;
		_month = 1;
	}
}
return *this;

}


### 3.3 +和+=相互复用定义比较


#### 复用+定义+=


简便很多



Date& Date::operator+=(int day)
{

*this = *this + day;
return *this;

}


####  复用+=定义 +


+= 不复用+来实现,那么+就可以复用 +=来实现



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


#### 到底谁复用谁效果更好呢?


![](https://img-blog.csdnimg.cn/12af695ac30d4058922bdf353921b11f.png)分别调用两种方式的+和+=


由拷贝构造的次数来看,+ 复用 += 效率会更高一些。


由此推出:- 复用 -= 效率会更高。


### 3.4 日期减天数‘-=’的重载


#### 声明



// 日期-=天数
Date& operator-=(int day);

#### 定义



> 
> **这里特别要注意的是当月份为0,时,重置月份,更新天数的时候,用更新后的月份来计算。**
> 
> 
> **最后返回\*this,不会销毁,用引用返回。**
> 
> 
> 
> **判断day为负的情况,复用 +=**
> 
> 
> **-=负值等价于+=正值:****:**
> 
> 
> 



Date& Date::operator-=(int day)
{
if (day<0)
{
return *this += -day;
}

_day -= day;
while (_day<=0)
{
	_month--;
	if (_month==0)
	{
		_month = 12;
		_year--;
	}

    //月份给的是前一个月,而不是原来的月份
    _day += GetMonthDay(_year,_month);
}

return *this;

}


### 3.5  日期减天数‘-’的重载


#### 声明



// 日期-天数
Date operator-(int day);

#### 用复用 -= 定义 -



Date Date::operator-(int day)
{
Date ret(*this);
ret -= day;
return ret;
}


## 4.日期 ++ 和 ++


### 4.1 ++


++运算符重载分为前置++和后置++,他们的函数形式如下:



// 前置++
Date& operator++();


// 后置++
Date operator++(int);


> 
> **函数名相同,为了区分开来,语法规定:**
> 
> 
> **没有参数的为前置++**
> 
> 
> **有参数的为后置++**
> 
> 
> 


#### 直接在类中定义


前置++,直接改变\*this的内容


后置++,\*this不变,返回的是此函数中构建好的临时变量,临时变量进行运算操作之后返回



// 前置++
Date& operator++()
{
	*this += 1;
	return *this;
}

// 后置++
Date operator++(int)
{
	Date ret(*this);
	ret += 1;
	return ret;
}

### 4.2 --


和++同理,直接在类中定义:



// 后置--
Date operator--(int)
{
	Date ret(*this);
	ret -= 1;
	return ret;
}

// 前置--
Date& operator--()
{
	*this -= 1;
	return *this;
}

## 5. 求日期差,返回天数


两个日期不相等时,求他们之间相差多少天


#### 声明



// 日期-日期 返回天数
int operator-(const Date& d);

### 思路



> 
> #### 第一思路:
> 
> 
> 年之间比较求差,月之间比较求差,天之间比较球差,最后判断对应天数,累加即可。
> 
> 
> 缺点:分别判断,分别计算,过程太繁琐
> 
> 
> #### 第二思路:
> 
> 
> 首先判断谁大谁小,让小的开始累加,直到和大的相等为止,只需要计加了多少天即可。 
> 
> 
> 


#### 定义



> 
> **这里flag来确定正负,如果现在和未来比,天数是正的,加上天数即可和大的相等**
> 
> 
> **如果是现在和过去比,天数是负的,现在+天数等于过去的时间**
> 
> 
> 



int Date::operator-(const Date& d)
{

int flag = 1;
Date max = *this;
Date min = d;
if (*this<d)
{
	min = *this;
	max = d;
	flag = -1;
}
//让小的累加至大的
//累加的天数n为差值
int n = 0;
while (min != max)
{
	n++;
	min++;
}

return n*flag;

}


## Date.h



#define _CRT_SECURE_NO_WARNINGS
#pragma once

#include
#include
using std::cout;
using std::cin;
using std::endl;

class Date
{
public:

// 获取某年某月的天数
bool Leapyear(int year)
{
	if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
	{
		return true;
	}
	else
	{
		return false;
	}
}

int GetMonthDay(int year, int month);


// 全缺省的构造函数
Date(int year = 1900, int month = 1, int day = 1)
{
	if (year < 1900 ||

		month < 1 || month > 12 ||

		day < 1 || day > GetMonthDay(year, month))

	{
		cout << "非法日期" << endl;
	}
	_year = year;

	_month = month;

	_day = day;
}



 拷贝构造函数
// d2(d1)
Date(const Date& d)
{
	cout << "构造拷贝" << endl;
	_year = d._year;

	_month = d._month;

	_day = d._day;
}



// 赋值运算符重载

// 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++()
{
	*this += 1;
	return *this;
}

// 后置++
Date operator++(int)
{
	Date ret(*this);
	ret += 1;
	return ret;
}



// 后置--
Date operator--(int)
{
	Date ret(*this);
	ret -= 1;
	return ret;
}

// 前置--
Date& operator--()
{
	*this -= 1;
	return *this;
}

// >运算符重载
bool operator>(const Date& d);



// ==运算符重载
bool operator==(const Date& d);



// >=运算符重载
inline 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 SetDate(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}
void Print()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

private:
int _year;
int _month;
int _day;
};


## Date.cpp



#define _CRT_SECURE_NO_WARNINGS

#include “Date.h”

// 赋值运算符重载

// d2 = d3 -> d2.operator=(&d2, d3)

Date& Date::operator=(const Date& d)
{
cout << “赋值” << endl;
if (*this != d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << “-” << _month << “-” << _day << endl;
}

private:
int _year;
int _month;
int _day;
};


## Date.cpp



#define _CRT_SECURE_NO_WARNINGS

#include “Date.h”

// 赋值运算符重载

// d2 = d3 -> d2.operator=(&d2, d3)

Date& Date::operator=(const Date& d)
{
cout << “赋值” << endl;
if (*this != d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}

[外链图片转存中…(img-rh3lwFPM-1715809873621)]
[外链图片转存中…(img-83sqv3jP-1715809873622)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值