🎬 胖咕噜的稞达鸭:个人主页

重难点:

这里重载为全局的面临对象访问私有成员变量的问题:
有4种解决方法:
- 1.成员放在公有(也就是把private注释掉);
- 2.Date提供getxxx函数;
- 3.友元函数;(随后介绍);
- 4.重载为成员函数。下面有图示:

2.重载为成员函数

#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
//private://1.成员放在公有位置,注释掉private
int _year;
int _month;
int _day;
};
//重载为全局的面临对象访问私有成员变量的问题
bool operator==(const Date& d1, const Date& d2)
{
return d1._year == d2._year
&& d1._month == d2._month
&& d1._day == d2._day;
}
int main()
{
Date d1(2025, 9, 18);
Date d2(2025, 9, 20);
d1.Print();
d2.Print();
return 0;
}
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
bool operator==(const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
private:
int _year;
int _month;
int _day;
};
//重载为全局的面临对象访问私有成员变量的问题:重载为成员函数
//bool operator==(const Date& d)
//{
// return _year == d._year
// && _month == d._month
// && _day == d._day;
//
//}
int main()
{
Date d1(2025, 9, 18);
Date d2(2025, 9, 20);
d1.operator==(d2);//运算符重载函数可以显示调用
d1 == d2;//编译器会转换成d1.operator==(d2);
return 0;
}
日期类实现更好理解赋值运算符重载,运算符重载


//Date.cpp
#include"Date.h"
//声明和定义分离
void Date::Print()const
{
cout << _year << "/" << _month << "/" << _day << endl;
}
bool Date::CheckDate()
{
if (_month > 12 || _month < 0 || _day<0 || _day> GetMonthDay(_year, _month))
{
return false;
}
else
{
return true;
}
}
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
if (!CheckDate())
{
cout << "日期非法" << endl;
}
}
//方法1:引用返回
Date& Date::operator+=(int day)//为了不改变原来的d1,所以这里用引用
{
_day += day;//先把天数加上去
while (_day > GetMonthDay(_year, _month))//如果超过当前月份的天数,就结束
{
_day -= GetMonthDay(_year, _month);
++_month;
if (_month == 13)
{
++_year;
_month = 1;
}
}
return *this;
}
//方法2:拷贝传值
Date Date::operator+(int day)
{
Date tmp = *this;//tmp拷贝一份d1,这里不改变d1的值
tmp._day += day;//先把天数加上去
while (tmp._day > GetMonthDay(tmp._year, tmp._month))//如果超过当前月份的天数,就结束
{
tmp._day -= GetMonthDay(tmp._year, tmp._month);
++tmp._month;
if (tmp._month == 13)
{
tmp._month = 1;
tmp. _year++;
}
}
return tmp;//返回tmp,局部对象
}
//
Date& Date::operator-=(int day)
{
_day -= day;
while (_day <= 0)//要进去循环一定是天数成了负数
{
--_month;
if (_month == 0)
{
_month = 12;
--_year;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
Date Date::operator-(int day)
{
Date tmp = *this;
tmp._day -= day;
while (tmp._day <= 0)
{
--tmp._month;
if (tmp._month == 0)
{
tmp._month == 12;
--tmp._year;
}
tmp._day += GetMonthDay(tmp._year, tmp._month);
}
return tmp;
}
//Date.h
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1);
void Print()const;
int GetMonthDay(int year, int month)
{
assert(month > 0 && month < 13);
//函数需要频繁调用,应该放到静态区
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];
}
}
bool CheckDate();
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;
//d1+=天数
Date& operator+=(int day);
Date operator+(int day);
Date operator-(int day);
Date& operator-=(int day);
private:
int _year;
int _month;
int _day;
};
//test.cpp
int main()
{
Date d1(2025, 9, 23);
Date d2 = d1 + 100;
Date d4 = d1 - 100;
d1.Print();//2025,9,23
d2.Print();//2026,1,1
d4.Print();//2025,6,15
return 0;
}
日期加减
//Date.cpp
//d1++
//d1.operator(0)后置++有拷贝
Date Date::operator++(int)
{
Date tmp (*this);//先保存当前对象的原始值
*this += 1;//对当前对象进行自增
return tmp;//返回原始值的拷贝
}
//++d1
//d1.operator()前置++没有拷贝
Date& Date::operator++()
{
*this += 1;//先对当前对象进行自增
return *this;//返回自增之后的对象引用
}
//d1--
//d1.operator(0)后置--有拷贝
Date Date::operator--(int)
{
Date tmp(*this);//先保存当前对象的原始值
*this -= 1;//对当前对象进行自增
return tmp;//返回原始值的拷贝
}
//--d1
//d1.operator()前置--没有拷贝
Date& Date::operator--()
{
*this -= 1;//先对当前对象进行自增
return *this;//返回自增之后的对象引用
}
//Date.h
Date& operator++();
Date operator++(int);
Date& operator--();
Date operator--(int);
//Test测试
#include"Date.h"
void TestDate01()
{
Date d1(2025, 9, 23);
Date ret1 = d1++;
ret1.Print();//2025 9 23 后置++返回值是++之前的值
d1.Print();//2025 9 24
Date d2(2025, 9, 23);
Date ret2 = ++d2;
ret2.Print();//2025 9 24 前置返回值++自己也要++
d2.Print();//2025 9 24
Date d3(2025, 9, 23);
Date ret3 = d3--;
ret3.Print();//2025 9 23
d3.Print();//2025 9 22
Date d4(2025, 9, 23);
Date ret4 = --d4;
ret4.Print();//2025 9 22
d4.Print();//2025 9 22
}
int main()
{
TestDate01();
return 0;
}
日期相减
//Date.cpp
//d1-d2
int Date::operator-(const Date& d)const
{
int flag = 1;
Date max = *this;
Date min = d;
if (*this < d)//假设认为d1大于d2,这里是假设错了走if循环进行判断
{
max = d;
min = *this;
flag = -1;//如果d1小,d2大,flag为负数,算出来的差值天数为负数,这里解决这个问题
}
int n = 0;
while (min != max)
{
++min;
++n;
}
return n * flag;
}
//Date.h
int operator-(const Date& d)const;
//Test2测试
#include"Date.h"
void TestDate2()
{
Date d5(2025, 9, 23);
Date d6(2025, 5, 21);
cout << d5 - d6 << endl;//125
}
int main()
{
TestDate2();
return 0;
}
流插入流提取算日期相差的天数:(在终端自己输入)
//Date.cpp
ostream& operator<<(ostream& out,const Date& d)
{
out << d._year << "年" << d._month << "月" <<d. _day << "日" << endl;
return out;
}
istream& operator>>(istream& in, Date& d)
{
while (1)
{
cout << "请依次输入年月日:>";
in >> d._year >> d._month >> d._day;
if (!d.CheckDate())
{
cout << "输入日期非法";
d.Print();
cout << "请重新输入:>" << endl;
}
else
{
break;
}
}
return in;
}
//Date.h
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
class Date
{
//友元函数,可以访问私有成员
friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& in, Date& d);
public:
Date(int year = 1900, int month = 1, int day = 1);
void Print()const;
int GetMonthDay(int year, int month)
{
assert(month > 0 && month < 13);
//函数需要频繁调用,应该放到静态区
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];
}
}
bool CheckDate();
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;
//d1+=天数
Date& operator+=(int day);
Date operator+(int day);
Date operator-(int day);
Date& operator-=(int day);
Date& operator++();
Date operator++(int);
Date& operator--();
Date operator--(int);
int operator-(const Date& d)const;
//void operator<<(ostream& out);
//private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);
//test测试:
#include"Date.h"
void TestDate3()
{
Date d1, d2;
//d1 << cout;//这样写不好看,调整不了参数,所以建议写成全局的
//d1.operator<<(cout);
cin >> d1 >> d2;
cout << d1 << d2;
operator<<(cout, d1);
cout << d1 - d2 << endl;
}
int main()
{
TestDate3();
return 0;
}


日期实现完整源码分享:
本章记录了博主在学习过程中遇到的一些问题:欢迎大家指正!





