c++中关于友元的知识点

#include <iostream>
using namespace std;
class x;
class y
{
public:
	void f(x);
};
class x
{
private:
	int i;
public:
	friend void y::f(x);
	friend void g(x, int);
};
void y::f(x x)
{
	x->i = 47;
}
void g(x xx,int i)
{
	xx->i = i;
}
int main()
{
	return 0;
}

//编译错误

    运行这段代码会出现编译错误的情况,这是因为c++编译器要求在引用任一变量之前必须声明,所以class y必须在它的成员y::f(x)被申明为class x的一个友元之前声明,但y::f(x)要被申明,class x又必须先声明,这样编译器根本无法正确操作,另外编译器也不知道y::g(x)这个函数的全部定义以确定它的大小以及如何传递它。

解决方法:在y::f(x*)引用一个x对象的地址。因为编译器知道如何传递一个地址,这一地址的大小是一定的,而不管被传递的对象类型大小。如果试图传递整个对象,编译器就必须知道x的全部定义以确定它的大小以及如何传递它。

    看下面修改过的代码:

#include <iostream>
using namespace std;
class x;
class y
{
public:
	void f(x*);
};
class x
{
private:
	int i;
public:
	friend void y::f(x*);
	friend void g(x*, int);
};
void y::f(x* x)
{
	x->i = 47;
}
void g(x* xx,int i)
{
	xx->i = i;
}
int main()
{
	return 0;
}
//编译成功

    通过传递x的地址,编译器允许程序员在声明y::f(x*)之前做一个不完全的类型指定。这一点是在class x的申明时完成的,这里仅仅告诉编译器,有一个叫x的class,所以当它被引用时不会产生错误,只要程序员的引用不涉及名字以外的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值