上一篇文章只实现了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();
}