【C++】-- 实现Date类的各种运算符重载

上一篇文章只实现了operator==操作符重载,由于运算符较多,该篇文章单独实现剩余所有的运算符重载。继续以Date类为例,实现运算符重载:

Date.h

#pragma once
#include<iostream>
#include<assert.h>

using namespace std;

class Date
{
public:
	//构造函数
	Date(int year = 0, int month = 1, int day = 0);

	//打印
	void Print() const;

	//Date类的成员变量全部都是内置类型,析构函数、拷贝构造函数、赋值运算符重载函数都可以不写,默认生成就够用
	//Stack类才需要写这三个函数

	//日期+整数
	Date& operator+=(int day);//日期被改变
	Date operator+(int day) const;//日期不会被改变
	
	//日期-整数
	Date& operator-=(int day);//日期被改变
	Date operator-(int day) const;//日期不会被改变


	//前置++和后置++都完成了++,不同的地方在于返回值不一样
	//++d 前置++  返回++之后的值 
	Date& operator++();

	//d++ 后置++  返回++之前的值
	Date operator++(int);//这里的int不需要给实参,没用该实参,它的作用是为了跟前置++构成函数重载

	//前置--和后置--都完成了--,不同的地方在于返回值不一样
	//--d 前置--  返回--之后的值
	Date& operator--();

	//d-- 后置--  返回--之前的值
	Date operator--(int);//这里的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;
	bool operator==(const Date& d) const;
	bool operator!=(const Date& d) const;

	//日期-日期,计算两个日期之间相差多少天
	int operator-(const Date& d) const;

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

Date.cpp

#include "Date.h"

//每次调用构造函数都会调用getMonthDay,定义成inline就没有函数压栈开销了
inline int getMonthDay(int year, int month)
{
	//数组存储平年每个月的天数,数组定义成static是为了避免每次调用getMonthDay时都要创建dayArray数组
	static int dayArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int day = dayArray[month];

	if ((month == 2) && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
	{
		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;
		assert(false);
	}	
}

void Date::Print() const
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

//d += day 日期+整数,日期被改变
Date& Date::operator+=(int day)//因为对象是在Test()中,即Date& Date::operator+=(int day)之外定义的
							   //出了该函数作用域,该对象还存在,可以用引用返回
{
	_day += day;

	//天不合法,不断进位,让天合法
	while (_day > getMonthDay(_year, _month))
	{
		_day -= getMonthDay(_year, _month);
		_month++;
		if (_month > 12)
		{
			_year++;
			_month = 1;
		}
	}

	return *this;//天数加到了*this上,返回*this
}

//d + day 日期+整数,日期不会被改变
Date Date::operator+(int day) const
{
	Date ret(*this);
	ret += day; //ret.operator+=(day)
				//复用+=,即调用Date& Date::operator+=(int day)函数,ret被改变,*this没有被改变
	return ret;
}

//d -= day 日期-整数,日期被改变
Date& Date::operator-=(int day)
{
	//判断day是否为负数
	if (day < 0)
	{
		*this += -day;
	}
	else
	{
		_day -= day;

		while (_day <= 0)
		{
			_day += getMonthDay(_year, _month - 1);
			_month--;

			if (_month < 1)
			{
				_year--;
				_month = 12;
			}
		}
	}

	return *this;//天数减到了*this上,返回*this
}

//d - day 日期整数,日期不会被改变
Date Date::operator-(int day) const
{
	Date ret(*this);
	ret -= day; //ret.operator+=(day)
				//复用+=,即调用Date& Date::operator+=(int day)函数,ret被改变,*this没有被改变
	return ret;
}

//++d ->d.operator++(&d)  前置++  返回++之后的值
Date& Date::operator++() 
{
	*this += 1;
	return *this;
}

//d++ ->d.operator+=(&d, 0) 后置++  返回++之前的值
Date Date::operator++(int)
{
	Date temp(*this);//将++之前的值保存起来
	*this += 1;
	return temp;
}

//--d ->d.operator--(&d)  前置--  返回--之后的值
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}

//d-- ->d.operator-=(&d, 0) 后置--  返回--之前的值
Date Date::operator--(int)
{
	Date temp(*this);//将--之前的值保存起来
	*this -= 1;
	return temp;
}


//比较运算符
//d1 > d2
bool Date::operator>(const Date& d) const
{
	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;
}

//d1 == d2
bool Date::operator==(const Date& d) const
{
	return (_year == d._year)
		&& (_month == d._month)
		&& (_day == d._day);
}

//d1 >= d2
bool Date::operator>=(const Date& d) const
{
	return *this > d || *this == d;
}

//d1 < d2
bool Date::operator<(const Date& d) const
{
	return !(*this >= d);
}

//d1 <= d2
bool Date::operator<=(const Date& d) const
{
	return !(*this > d);
}

//d1 != d2
bool Date::operator!=(const Date& d) const
{
	return !(*this == d);
}

//日期-日期,计算两个日期之间相差多少天
int Date::operator-(const Date& d) const
{
	//找出this和d哪个大
	Date max = *this;//假设this大
	Date min = d;
	int flag = 1;//可能两个日期相减值为负数,将flag作为标志位进行记录

	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}

	int n = 0;
	while (min != max)//使用operator!=运算符重载
	{
		min++;
		n++;
	}
	return flag * n;
}

Test.cpp

#include "Date.h"
void Test1()
{
	Date d1(2022, 4, 18);
	d1.Print();

	d1 += 100;
	d1.Print();//d1被改变

	//用d2来接收operator+的返回值
	Date d2 = d1 + 3;
	d2.Print();
	d1.Print();//d1未被改变
}

void Test2()
{
	Date d1(2022, 4, 18);
	d1.Print();

	d1 -= 100;
	d1.Print();//d1被改变

	//用d3来接收operator-的返回值
	Date d3 = d1 + 3;
	d3.Print();
	d1.Print();//d1未被改变
}

void Test3()
{
	Date d1(2022, 4, 18);
	d1.Print();

	Date ret = ++d1;//前置++,返回++之后的值,用ret来接收返回值,和Test4()中的返回值不同
	ret.Print();//
	d1.Print();
}

void Test4()
{
	Date d1(2022, 4, 18);
	d1.Print();

	Date ret = d1++;//后置++,返回++之前的值,用ret来接收返回值,和Test3()中的返回值不同
	ret.Print();
	d1.Print();
}

void Test5()
{
	Date d1(2022, 4, 18);
	Date d2(2022, 12, 18);

	int ret = d1 - d2;
	cout << ret << endl;
}

int main()
{
	Test5();
}

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值