友元成员函数怎么用?

        友元破坏了类的封装性,能够让友元的类或函数访问到类的私有数据,既然它有这个特性那就看看怎么使用吧,这里看个友元成员函数的使用。

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

class CDate;
class CTime
{
public:
	void showDate(CDate &date)
	{
		printf("%d-%d-%d \n", date.mYear, date.mMonth, date.mDay);
	}
};

class CDate
{
	friend void CTime::showDate(CDate &date);
public:
	CDate(int y, int m, int d): mYear(y), mMonth(m), mDay(d)
	{
		
	}
private:
	int mYear;
	int mMonth;
	int mDay;
};

int main()
{
	CDate date(2024, 8, 30);
	CTime time;
	time.showDate(date);
	
	return 0;
}

看这个代码的意图是想在类 CTime j里通过传进来的 CDate 对象直接访问CDate的私有数据,没有友元的情况下,是无法直接访问类的私有数据的。但这样使用最直接的错误就是找不到 CDate的定义,编译错误如下 :

 

有人会说不是有个前置声明吗?然而这个 class CDate; 前置声明对声明这个类型的指针是有效的,因为指针的大小是固定的(4字节或8字节),不管定义什么类型的指针其大小都是固定的,它不关心指针指向的具体的数据类型。但非指针定义就需要知道这个类型的具体结构,因为为分配相应的内存大小。以下改成指针类型的,但也不能访问数据,只是能编译成功而已:
 

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

class CDate;
class CTime
{
public:
	void showDate(CDate *date)
	{
		//printf("%d-%d-%d \n", date.mYear, date.mMonth, date.mDay);
	}
};

class CDate
{
	friend void CTime::showDate(CDate *date);
public:
	CDate(int y, int m, int d): mYear(y), mMonth(m), mDay(d)
	{
		
	}
private:
	int mYear;
	int mMonth;
	int mDay;
};

int main()
{
	CDate date(2024, 8, 30);
	CTime time;
	time.showDate(&date);
	
	return 0;
}

那怎么解决上面的问题呢?那就是那个友元成员函数只在类里声明,在类外定义即可。如:

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

class CDate;
class CTime
{
public:
	void showDate(CDate &date);
};

class CDate
{
	friend void CTime::showDate(CDate &date);
public:
	CDate(int y, int m, int d): mYear(y), mMonth(m), mDay(d)
	{
		
	}
private:
	int mYear;
	int mMonth;
	int mDay;
};

void CTime::showDate(CDate &date)
{
	printf("%d-%d-%d \n", date.mYear, date.mMonth, date.mDay);
}

int main()
{
	CDate date(2024, 8, 30);
	CTime time;
	time.showDate(date);
	
	return 0;
}

 编译器毕竟是从上到下进行编译,到编译 void CTime::showDate(CDate &date) 时,已经有了 CDate 的定义了,所以编译器知道这个 CDate 的大小及数据结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值