什么是友元?什么可以做友元?友元能干什么?(全局函数做友元,类做友元,成员函数做友元)c/c++

一、 什么是友元

例如:你的生活中有一个特别好的朋友,你允许它进入你的房间(私有场所)也允许他进入客厅(相对公有场所),但是对于其他人你是不会允许他进入你的房间的,只允许他进入客厅。类对象也有这样类似的好朋友类,可以访问本类的私有成员,这个好朋友类就叫做这个类的友元,友元也可以是全局函数和别的类的成员函数,下面一一解答。

二、全局函数做友元

2.1创建建筑类

我们创建一个建筑类,这个建筑类里有私有成员卧室和公有成员客厅,和他的构造函数。

class Building
{
	//friend void Godgay(Building& building);
public:
	Building()
	{
		SittingRoom = "客厅";
		BedRoom = "卧室";
	}
public:
	string SittingRoom;
private:
	string BedRoom;

};

2.2创建好基友全局函数

然后我们再创建一个全局函数叫做好基友函数,我们让这个函数里面分别访问建筑类的卧室(私有)和客厅(公有)。我们会发现访问卧室时会报错,原因是因为卧室是建筑类私有成员,那么我们该如何访问这个私有成员呢,我们只需要让这个全局函数成为建筑类的友元即可,实现就是在建筑类的最上面加上friend和该全局函数的声明就可以了。

void Godgay(Building& building)
{
	cout << "好基友正在访问:" << building.SittingRoom << endl;
	cout << "好基友正在访问:" << building.BedRoom << endl;

}

2.3代码运行结果

运行结果如下
在这里插入图片描述
可以看到正常输出了好基友访问卧室。

2.4全局函数做友元全部代码

#include<iostream>
using namespace std;

class Building
{
	friend void Godgay(Building& building);
public:
	Building()
	{
		SittingRoom = "客厅";
		BedRoom = "卧室";
	}
public:
	string SittingRoom;
private:
	string BedRoom;

};

void Godgay(Building& building)
{
	cout << "好基友正在访问:" << building.SittingRoom << endl;
	cout << "好基友正在访问:" << building.BedRoom << endl;

}

void test01()
{
	Building building;
	Godgay(building);
}
int main() {

	test01();
	system("pause");
	return 0;
}

三、类做友元

3.1创建建筑类

同样我们创建一个建筑类;里面有卧室(私有)和客厅(公有),(注意这里用到了成员函数的类外实现,即当我们创建类时在类内只写声明类外写实现。)

class Building
{
//不加下面这行代码时会报错,加了以后就可以实现友元,
//好基友类既可以正常访问建筑类的私有成员了
	friend class GodGay;
public:
	Building();
public:
	string SittingRoom;
private:
	string BedRoom;

};

Building::Building()
{
	SittingRoom = "客厅";
	BedRoom = "卧室";
}

3.2创建好基友类

然后我们创建一个好基友类,实现如下:(注意这里用到了成员函数的类外实现,即当我们创建类时在类内只写声明类外写实现。),在好基友类的构造函数中我们初始化了*building,(我们也可以不用指针直接创建一个建筑类对象,这里为了更好的练习我就使用了指针)

class GodGay
{

public:
	void visit();
	GodGay();
private:
	Building *building;
};


GodGay::GodGay()
{

	building=new Building;
	//Building building;
}

void GodGay::visit()
{
	cout << "好基友正在访问:" << building->SittingRoom << endl;
	cout << "好基友正在访问:" << building->BedRoom << endl;

}

3.3运行结果

运行结果如下
在这里插入图片描述
可以看到正常输出了访问卧室。

3.4类做友元全部代码

#include<iostream>
using namespace std;

class Building;

class Building
{
	friend class GodGay;
public:
	Building();
public:
	string SittingRoom;
private:
	string BedRoom;

};

Building::Building()
{
	SittingRoom = "客厅";
	BedRoom = "卧室";
}


class GodGay
{

public:
	void visit();
	GodGay();
private:
	Building *building;
};


GodGay::GodGay()
{

	building=new Building;
	//Building building;
}

void GodGay::visit()
{
	cout << "好基友正在访问:" << building->SittingRoom << endl;
	cout << "好基友正在访问:" << building->BedRoom << endl;

}
void test01()
{
	GodGay gg;
	gg.visit();
}
int main() {

	test01();
	system("pause");
	return 0;
}

四、成员函数做友元

4.1创建建筑类

class Building
{
//成员函数做友元时我们要标明该成员函数是那个类的成员函数,
//这是和全局函数做友元的不同之处
	friend void GoodGay::visit1();
public:
	Building();
public:
	string m_SittingRoom;
private:
	string m_BedRoom;
};

Building::Building()
{
	m_BedRoom = "卧室";
	m_SittingRoom = "客厅";
}

4.2创建好基友成员函数

成员函数做友元和类做友元的区别就是类做友元,类中的所有成员函数都可以访问建筑类的私有成员,但成员函数做友元,只有该成员函数可以访问建筑类的私有成员,该类中其他不是友元的成员还有不可以访问建筑类的私有成员,为了显示出这一特性我们在下面的好基友类中创建两个成员函数一个做建筑类的友元,一个不做友元对比。下面是好基友类的实现(因为在堆区开辟了空间所以我们在析构函数中释放该空间,养成良好习惯)

class GoodGay
{
public:
	GoodGay();
	~GoodGay();
	void visit1();//让他可以访问Building的私有成员
	void visit2();//让他不可以访问Building的私有成员
private:
	Building* building;
};

GoodGay::GoodGay()
{
	building = new Building;
}

GoodGay::~GoodGay()
{
	if(building!=NULL)
	{ 
		delete building;
		building = NULL;
	}
	
}

void GoodGay::visit1()
{
	cout << "好基友正在访问:" << building->m_SittingRoom << endl;
	cout << "好基友正在访问:" << building->m_BedRoom << endl;
}

void GoodGay::visit2()
{
	cout << "好基友正在访问:" << building->m_SittingRoom << endl;
//	cout << "好基友正在访问:" << building->m_BedRoom << endl;
}

4.3运行结果

在这里插入图片描述
我们发现做友元的visit1()可以正常访问建筑类的私有成员,但是visit2()不行,没有输出访问卧室。这就是成员函数做友元。

4.4成员函数做友元全部代码

#include<iostream>
using namespace std;

class Building;
class GoodGay
{
public:
	GoodGay();
	~GoodGay();
	void visit1();//让他可以访问Building的私有成员
	void visit2();//让他不可以访问Building的私有成员
private:
	Building* building;
};

class Building
{
	friend void GoodGay::visit1();
public:
	Building();
public:
	string m_SittingRoom;
private:
	string m_BedRoom;
};

Building::Building()
{
	m_BedRoom = "卧室";
	m_SittingRoom = "客厅";
}

GoodGay::GoodGay()
{
	building = new Building;
}

GoodGay::~GoodGay()
{
	if(building!=NULL)
	{ 
		delete building;
		building = NULL;
	}
	
}

void GoodGay::visit1()
{
	cout << "好基友正在访问:" << building->m_SittingRoom << endl;
	cout << "好基友正在访问:" << building->m_BedRoom << endl;
}

void GoodGay::visit2()
{
	cout << "好基友正在访问:" << building->m_SittingRoom << endl;
	//不是友元,会报错
//	cout << "好基友正在访问:" << building->m_BedRoom << endl;
}

void test01()
{
	GoodGay gg;
	gg.visit1();
	gg.visit2();

}
int main() {

	test01();
	system("pause");
	return 0;
}

五、总结

5.1三者做友元的不同

全局函数只需要加friend关键词和函数声明,但是成员函数做友元要表明成员函数的出处。
类做友元类中友元类的所有成员函数都可访问该类的私有成员,但成员函数做友元只有该成员函数可以访问该类的私有成员。

5.2三者做友元的相同之处

做友元都是要在类中加上friend关键字和声明

声明以上所有内容都是本人跟着黑马程序员学习之后做的总结,不会用于商业用途,只用作平时联系和分享,链接如下个人感觉链接讲的更加细致。
黑马程序员学C++

  • 18
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值