C++友元类和友元函数

特点:

  • 能访问私有成员
  • 破坏封装性
  • 友元关系不可传递。若B是A的友元,C是B的友元,但C不一定是A的友元,要看类中是否有申明。
  • 友元关系的单向性。若A是B的友元,但B不一定是A的友元,要看类中是否申明。
  • 友元声明的形式及数量不受限制

为什么需要友元:

        在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。

友元的作用:

       友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元的三种实现:

  1. 全局函数做友元
#include <iostream>
#include <string>
using namespace std;
// 房屋类
class Building
{
	// 告诉编译器 laoWang全局函数是 Building类  的好朋友,可以访问Building对象的私有成员
	friend void laoWang1(Building *building);
	friend void laoWang2(Building &building);
	friend void laoWang3(Building building);
public:
	Building()
	{
		m_SittingRoom = "客厅";
		m_BedRoom = "卧室";
	}
	string m_SittingRoom;	// 客厅
private:
	string m_BedRoom;		// 卧室
};
//全局函数
void laoWang1(Building *building)
{
	cout << "隔壁老王 全局函数 正在访问:(地址传递) " << building->m_SittingRoom << endl;
	cout << "隔壁老王 全局函数 正在访问:(地址传递) " << building->m_BedRoom << endl;
}
void laoWang2(Building &building)
{
	cout << "隔壁老王 全局函数 正在访问:(引用传递) " << building.m_SittingRoom << endl;
	cout << "隔壁老王 全局函数 正在访问:(引用传递) " << building.m_BedRoom << endl;
}

void laoWang3(Building building)
{
	cout << "隔壁老王 全局函数 正在访问:( 值传递 ) " << building.m_SittingRoom << endl;

	cout << "隔壁老王 全局函数 正在访问:( 值传递 ) " << building.m_BedRoom << endl;
}
void test()
{
	Building building;
	laoWang1(&building);
	laoWang2(building);
	laoWang3(building);
}
int main()
{
	test();
}
//结果:
//隔壁老王 全局函数 正在访问:(地址传递) 客厅
//隔壁老王 全局函数 正在访问:(地址传递) 卧室
//隔壁老王 全局函数 正在访问:(引用传递) 客厅
//隔壁老王 全局函数 正在访问:(引用传递) 卧室
//隔壁老王 全局函数 正在访问:( 值传递 ) 客厅
//隔壁老王 全局函数 正在访问:( 值传递 ) 卧室
  1. 类做友元
#include <iostream>
#include <string>
using namespace std;
// 类作友元
class Building;
class LaoWang
{
public:
	LaoWang();
	void visit();	//参观函数  访问Building中的属性
	Building * building;
private;
};
// 房屋类
class Building
{
	// 告诉编译器,LaoWang类是Building类的好朋友,可以访问Building类的私有成员
	friend class LaoWang;
public:
	Building();
	string m_SittingRoom;	// 客厅
private:
	string m_BedRoom;		// 卧室
};
// 类外定义成员函数
Building::Building()
{
	m_SittingRoom = "客厅";
	m_BedRoom = "卧室";
}
LaoWang::LaoWang()
{
	// 创建建筑物对象
	building = new Building;
}
void LaoWang::visit()
{
	cout << "隔壁老王LaoWang类正在访问:" << building->m_SittingRoom << endl;
	cout << "隔壁老王LaoWang类正在访问:" << building->m_BedRoom << endl;
}
void test()
{
	LaoWang lw;
	lw.visit();
}
int main()
{
	test();
	return 0;
}
//结果
//隔壁老王LaoWang类正在访问:客厅
//隔壁老王LaoWang类正在访问:卧室
  1. 成员函数做友元
#include <iostream>
#include <string>

using namespace std;

class Building;

class LaoWang
{
public:

	LaoWang();
	void visit1();	//让visit1()函数   可以 访问Building中的私有成员
	void visit2();	//让visit2()函数 不可以 访问Building中的私有成员

	Building *building;

private:

	
};

class Building
{
	// 告诉编译器,LaoWang类下的visit1()函数是Building类的好朋友,可以访问Building的私有成员
	friend void LaoWang::visit1();

public:
	Building();

	string m_SittingRoom;	//客厅
private:

	string m_BedRoom;		//卧室
};


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

void LaoWang::visit1()
{
	cout << "隔壁老王LaoWang类中的visit1()函数正在访问:" << building->m_SittingRoom << endl;
	cout << "隔壁老王LaoWang类中的visit1()函数正在访问:" << building->m_BedRoom << endl;
}

void LaoWang::visit2()
{
	cout << "隔壁老王LaoWang类中的visit2()函数正在访问:" << building->m_SittingRoom << endl;
	//cout << "隔壁老王LaoWang类中的visit2()函数正在访问:" << building->m_BedRoom << endl;	//错误!私有属性不可访问
}

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

void test()
{
	LaoWang lw;
	
	lw.visit1();

	lw.visit2();
}

int main()
{
	test();
	
	return 0;
}
//结果
//隔壁老王LaoWang类中的visit1()函数正在访问:客厅
//隔壁老王LaoWang类中的visit1()函数正在访问:卧室
//隔壁老王LaoWang类中的visit2()函数正在访问:客厅
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值