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

从自定义日期类角度解析运算符重载,友元函数(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.dtcms.com/a/357625.html

相关文章:

  • AI助力PPT创作:秒出PPT与豆包AI谁更高效?
  • 实现动态数组
  • 【NJU-OS-JYY笔记】操作系统:设计与实现
  • 【开题答辩全过程】以 基于Vue Spring Boot的教师资格证考试助力系统设计与实现为例,包含答辩的问题和答案
  • 黑客之都CSP-J模拟赛题解
  • C6.6:交流参量、电压增益、电流增益的学习
  • 企业级-搭建CICD(持续集成持续交付)实验手册
  • 【面试场景题】三阶段事务提交比两阶段事务提交的优势是什么
  • TypeScript: Symbol.iterator属性
  • 蓝蜂蓝牙模组:破解仪器仪表开发困境
  • 打通安卓、苹果后,小米澎湃OS 3又盯上了Windows
  • 【系列05】端侧AI:构建与部署高效的本地化AI模型 第4章:模型量化(Quantization)
  • AntSK知识库多格式导入技术深度解析:从文档到智能,一站式知识管理的技术奇迹
  • 第十二节 Spring 注入集合
  • 零知识证明的刑事证据困境:隐私权与侦查权的数字博弈
  • Windows 11 跳过 OOBE 的方法和步骤
  • 企业级数据库管理实战(二):数据库权限最小化原则的落地方法
  • 现状摸底:如何快速诊断企业的“数字化健康度”?
  • 嵌入式Linux驱动开发 - 蜂鸣器驱动
  • 25.8.29_NSSCTF——[BJDCTF 2020]Easy_WP
  • VeOmni 全模态训练框架技术详解
  • 深入理解Go 与 PHP 在参数传递上的核心区别
  • 变量声明方式
  • 嵌入式第四十一天(数据库)
  • 海量小文件问题综述和解决攻略(二)
  • C++ DDS框架学习
  • 超详细讲解urllib库的使用
  • 【C语言初阶】指针_野指针,指针运算
  • UCIE Specification详解(九)
  • 马斯克杀入AI编程!xAI新模型Grok Code Fast 1发布,深度评测:速度、价格与API上手指南