当前位置: 首页 > java >正文

从自定义日期类角度解析运算符重载,友元函数(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函数中进行相应的调用即可。
在这里插入图片描述
觉得我回答有用的话,记得点个关注哟!谢谢支持!

http://www.xdnf.cn/news/19178.html

相关文章:

  • Java中使用Spring Boot+Ollama实现本地AI的MCP接入
  • Dify平台:Agent开发初学者指南
  • Mybatis的常用标签
  • 高精度惯性导航供应商价格解析
  • 【Java基础|第三十篇】File流
  • GitHub 宕机自救指南:打造韧性开发体系
  • 多方调研赋能AI+智慧消防 豪越科技人工智能创新获认可
  • 飞牛Nas每天定时加密数据备份到网盘,基于restic的Backrest笔记分享
  • C# WinForms 使用 CyUSB.dll 访问 USB 设备
  • 第6.4节:awk语言 for 语句
  • Java ThreadLocal为什么要用弱引用
  • 2025最新:Salesforce认证考试—考试中心预约全流程
  • 香港电讯为知名投资公司搭建高效、安全IT管理服务体系
  • GraphRAG 知识图谱核心升级:集成 langextract 与 Gemini ----实现高精度实体与关系抽取
  • 营业执照识别技术应用OCR与深度学习,实现高效、精准提取企业核心信息,推动数字化管理发展。
  • Linux时间处理函数
  • 机器学习(三)sklearn机器学习
  • 第二阶段WinForm-11:自定义控件
  • Java全栈工程师的面试实战:从技术细节到业务场景
  • 在八月点燃AI智慧之火:CSDN创作之星挑战赛开启灵感盛宴
  • 04.《VLAN基础与配置实践指南》
  • Django Admin 管理工具
  • NSSCTF-[NISACTF 2022]string_WP
  • 身份证实名认证API集成—身份核验接口-网络平台安全合规
  • mitmproxy的使用初试
  • windows中Qwen3‑Coder 与 Claude Code 搭配使用
  • 《UE5_C++多人TPS完整教程》学习笔记45 ——《P46 待机与跳跃动画(Idle And Jumps)》
  • 【完整源码+数据集+部署教程】植物病害检测系统源码和数据集:改进yolo11-EMSCP
  • Lombok vs Java Record:谁才是未来?
  • week5-[二维数组]翻转