C++——友元函数

如下是一个日期类:

cpp 复制代码
class Date
{
public:
	Date(int year = 2023, int month = 10, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
		if (_month < 1 || month > 12 || _day < 1 || _day > GetMonthDay(_year, _month))
		{
			cout << "日期不规范" << endl;
			//exit(-1);  终止程序
		}
	}
	//拷贝构造函数
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void print() const //const 放在这里,指的是this指针为const Date*类型,这样就可以让const Date类型进行print了
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	int GetMonthDay(int year, int month)//获取某面某月的天数
	{
		//加static,可以省去每次访问时都开辟数组空间。
		static int MonthArray[] = { 0,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;
		return MonthArray[month];
	}
	//赋值运算符
	//返回类型为Date,支持连续赋值
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;//*this出了函数还在,就可以使用引用返回。
	}
private:
	int _year;
	int _month;
	int _day;
};

假设我们不使用日期类的print函数,通过<<符号重载,能不能实现日期类的打印?

然后使用:

发现这时无法使用的

原因:

这个内部函数的第一个参数,也就是<<左边的操作数,是this,为日期类

第二个参数为<<右侧的操作数out,为ostream类。

而我们调用的时候,cout << d1,左侧写的是ostream类,右侧写的是日期类,顺序发生了错误。

只要我们将顺序调换就可以正常使用了,但是这不太符合我们平时的使用习惯

要想手动设置两个参数的位置,就不能将其实现为内部的成员函数,而是类外部的函数:

但是,这样,类内部的private参数就不能访问了

这里的解决方法就是实现这个类的各种参数的set和get方法,但是这样有点麻烦

还有一种解决方式,就涉及到了友元。

友元:

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以要尽可能减少使用。

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加上friend关键字。

如下:

【BTW】:为了实现能够连续调用,返回类型改成了ostream类型

友元声明可以放在类内的任何地方。

这样就可以实现了<<的重载了。

同理,实现>>的重载,总体如下:

相关推荐
Sakura_j_h_2 小时前
EasyEDA PCB 快速设计Skills
c++·python·github
程序喵大人3 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
jimy15 小时前
C++ 中的 `T&&`:右值引用与转发引用
开发语言·c++
会编程的小孩7 小时前
C++ 定时器
c++
沫璃染墨8 小时前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
揽星河..10 小时前
【C语言】分支和循环
c语言·c++·算法
Fuyo_111911 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
傲世仙尊12 小时前
继承-类设计层次复用切片转换与菱形继承的死结
c++
架构师伯子明12 小时前
FFmpeg C++学习(一):编译和demo
开发语言·c++·学习
纪念 22913 小时前
C++算法(六)
开发语言·c++·算法