C++篇 类和对象(3)万能工具怎么用?

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

🔥 个人专栏: 《数据结构《C++初阶高阶》

⛺️技术的杠杆,撬动整个世界!

在这里插入图片描述
重难点:
在这里插入图片描述

这里重载为全局的面临对象访问私有成员变量的问题:

有4种解决方法:

  1. 1.成员放在公有(也就是把private注释掉);
  2. 2.Date提供getxxx函数;
  3. 3.友元函数;(随后介绍);
  4. 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;
}

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

评论 20
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值