从自定义日期类角度解析运算符重载,友元函数(friend)
文章目录
- 运算符重载
- Date.h
- Data.cpp
- 更新Date.h
- 重载+,+=(日期+/+=天数)
- 重载-,-=(日期-/-=天数)
- 重载 <,<=,>,>=,==,!= (日期 比较 日期)
- 重载 前置++和后置++ (++日期或日期++)
- 重载 -(日期-日期)
- 重载流插入
- 重载流提取
- 源码
- Date.h
- Date.cpp
运算符重载
Date.h
首先定义我们的日期类。在日期类中深入理解+,+= ,-,-=,<,<=,>,>=,==,!=,++,-- 。
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>class Date {
public:Date(int year, int month, int day);void print() const;Date(const Date&d);int GetYear() {return _year;}int GetMonth() {return _month;}int GetDay() {return _day;}
private:int _year;int _month;int _day;
};
Data.cpp
在Data.cpp中声明函数。
#include"Date.h"Date::Date(int year, int month, int day) {_year = year;_month = month;_day = day;
}void Date::print() const {cout << _year << "-" << _month << "-" << _day << endl;
}Date::Date(const Date& d) {_year = d._year;_month = d._month;_day = d._day;
}
在后续板块中,第一部分的代码放在Date.h中,第二部分的代码放在Date.cpp中。
在日期中为了快速获得某年某月的天数,需要在Date.h中写一个函数获取具体的天数。
更新Date.h
在Date.h中写入GetMonthDay()函数,用于获取某年某月的天数,在类里面写入的成员函数默认是inline修饰的内联函数。生命周期和函数的生命周期一样。
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>class Date {
public:Date(int year, int month, int day);void print() const;Date(const Date&d);//默认是inline
//用inline修饰的函数叫内联函数,可以提高编程效率
int GetMonthDay(int year, int month) {//此数组需要频繁的调用,放入静态区//静态区的生命周期和程序的生命周期一样static int MonthDayArray[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {return 29;}else {return MonthDayArray[month];}}int GetYear() {return _year;}int GetMonth() {return _month;}int GetDay() {return _day;}
private:int _year;int _month;int _day;
};
重载+,+=(日期+/+=天数)
重载+,想要知道一个日期加上day天后的是什么日期,原有的日期不变。
重载+=,想知道一个日期加上day天后原有的日期会变成什么日期,原有的日期需要改变。
Date operator+(int day) const;
//返回引用(Date&)直接操作原对象,无额外拷贝开销。
Date& operator+=(int day);
要明白日期加天数日期本身是不会变化的。所以在(+)重载中不能改变原有的日期。
Date Date::operator+(int day) const {//日期加天数 原有的日期不变需要进行创建临时thisDate tmp = *this;//+=进行了赋值重载tmp += day;return tmp;
}Date& Date::operator+=(int day) {if (day < 0) {return *this -= (-day);}_day += day;while (_day > GetMonthDay(_year, _month)) {_day -= GetMonthDay(_year, _month);if (_month > (_month + 1)%12 ) {_year++;}_month = (_month + 1) % 12;}return *this; //返回当前对象的引用
}
重载-,-=(日期-/-=天数)
重载-,想要知道一个日期减上day天后的是什么日期,原有的日期不变。
重载-=,想知道一个日期减上day天后原有的日期会变成什么日期,原有的日期需要改变。
Date operator-(int day) const;
Date& operator-=(int day);
要明白日期j减天数日期本身是不会变化的。所以在(-)重载中不能改变原有的日期。
Date Date::operator-(int day) const {Date tmp = *this;tmp -= day;return tmp;
}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;}
重载 <,<=,>,>=,==,!= (日期 比较 日期)
在以下的重载中,写出两个,便可以推出其余重载。
进行对两个日期的对比。
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;
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) {return _day < d._day;}}return false;
}bool Date::operator<=(const Date& d) const {return *this < d || *this == d;
}bool Date::operator>(const Date& d) const {return !(*this <= d);
}
bool Date::operator>=(const Date& d) const {return *this > d || *this == d;
}
bool Date::operator==(const Date& d) const {return _year == d._year && _month == d._month && _day == d._day;
}
bool Date::operator!=(const Date& d) const {return !(*this == d);
}
重载 前置++和后置++ (++日期或日期++)
//d1++
Date operator++(int);
//++d1
Date& operator++();
//d1++
Date Date::operator++(int) {Date tmp = *this;tmp += 1;return tmp;
}
//++d1
Date& Date::operator++() {return *this += 1;
}
重载 -(日期-日期)
int operator-(const Date& d);
int Date:: operator-(const Date& d) {Date max = *this;Date min = d;int flag = 1;if (max < min) {swap(max, min);flag = -1;}int cnt = 0;while (max != min) {++min;cnt++;}return cnt * flag;
}
重载流插入
这样重载依旧符合用户习惯。
ostream& operator<<(ostream& out, const Date& d);
ostream& operator<<(ostream& out, const Date& d) {//out就是coutout << d._year << "-" << d._month << "-" << d._day << endl;return out;
}
重载流提取
//流提取
istream& operator>>(istream& in, Date& d);
//流提取
istream& operator >> (istream& in, Date& d) {in >> d._year >> d._month >> d._day;return in;
}
源码
Date.h
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>class Date {//友元函数//友元函数可以访问私有成员friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
public:Date(int year = 1990, int month = 1, int day = 1);//未加const前 Date* const this;//加上const后 const Date* const this;void print() const;Date(const Date&d);//默认是inline//用inline修饰的函数叫内联函数,可以提高编程效率int GetMonthDay(int year, int month) {//此数组需要频繁的调用,放入静态区//静态区的生命周期和程序的生命周期一样static int MonthDayArray[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {return 29;}else {return MonthDayArray[month];}}int GetYear() {return _year;}int GetMonth() {return _month;}int GetDay() {return _day;}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;Date operator+(int day) const;//返回引用(Date&)直接操作原对象,无额外拷贝开销。Date& operator+=(int day);Date operator-(int day) const;Date& operator-=(int day);//d1++Date operator++(int);//++d2Date& operator++();int operator-(const Date& d);/*void operator<<(ostream& out);*/Date* operator&() {return this;}const Date* operator&() const {return this;}
//private:
private:int _year;int _month;int _day;
};//流插入
ostream& operator<<(ostream& out, const Date& d);//流提取
istream& operator>>(istream& in, Date& d);
Date.cpp
#include"Date.h"Date::Date(int year, int month, int day) {_year = year;_month = month;_day = day;
}void Date::print() const {cout << _year << "-" << _month << "-" << _day << endl;
}Date::Date(const Date& d) {_year = d._year;_month = d._month;_day = d._day;
}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) {return _day < d._day;}}return false;
}bool Date::operator<=(const Date& d) const {return *this < d || *this == d;
}bool Date::operator>(const Date& d) const {return !(*this <= d);
}
bool Date::operator>=(const Date& d) const {return *this > d || *this == d;
}
bool Date::operator==(const Date& d) const {return _year == d._year && _month == d._month && _day == d._day;
}
bool Date::operator!=(const Date& d) const {return !(*this == d);
}Date Date::operator+(int day) const {//日期加天数 原有的日期不变需要进行创建临时this//法一/*Date tmp = *this;tmp._day += day;while (tmp._day > GetMonthDay(tmp._year, tmp._month)) {tmp._day -= GetMonthDay(tmp._year, tmp._month);if (tmp._month > (tmp._month + 1) % 12) {tmp._year++;}tmp._month = (tmp._month + 1) % 12;}return tmp;*///法二Date tmp = *this;//+=进行了赋值重载tmp += day;return tmp;
}Date& Date::operator+=(int day) {if (day < 0) {return *this -= (-day);}_day += day;while (_day > GetMonthDay(_year, _month)) {_day -= GetMonthDay(_year, _month);if (_month > (_month + 1)%12 ) {_year++;}_month = (_month + 1) % 12;}return *this; //返回当前对象的引用
}Date Date::operator-(int day) const {Date tmp = *this;tmp -= day;return tmp;
}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;}//d1++
Date Date::operator++(int) {Date tmp = *this;tmp += 1;return tmp;
}
//++d2
Date& Date::operator++() {return *this += 1;
}int Date:: operator-(const Date& d) {Date max = *this;Date min = d;int flag = 1;if (max < min) {swap(max, min);flag = -1;}int cnt = 0;while (max != min) {++min;cnt++;}return cnt * flag;
}//void Date::operator<<(ostream& out) {
// //out就是cout
// out << _year << "-" << _month << "-" << _day << endl;
//}
//d6 << cout;
//d6.operator<<(cout);//流插入
ostream& operator<<(ostream& out, const Date& d) {//out就是coutout << d._year << "-" << d._month << "-" << d._day << endl;return out;
}//流提取
istream& operator >> (istream& in, Date& d) {in >> d._year >> d._month >> d._day;return in;
}
以上就是运算符重载的源码,只需要在main函数中进行相应的调用即可。
觉得我回答有用的话,记得点个关注哟!谢谢支持!