首页 > 编程语言 >什么是友元?什么可以做友元?友元能干什么?(全局函数做友元,类做友元,成员函数做友元)c/c++

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

时间:2024-08-26 15:24:17浏览次数:12  
标签:友元 Building building 成员 做友元 GoodGay SittingRoom 函数

一、 什么是友元

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

二、全局函数做友元

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++

标签:友元,Building,building,成员,做友元,GoodGay,SittingRoom,函数
From: https://blog.csdn.net/m0_57094953/article/details/141458882

相关文章

  • MySQL常用的分组聚合函数
    一、聚合函数(aggregationfunction)---也就是组函数在一个行的集合(一组行)上进行操作,对每个组给一个结果。常用的组函数:AVG([distinct]expr)求平均值COUNT({*|[distinct]}expr)统计行的数量MAX([distinct]expr)求最大值MIN([distinct]exp......
  • 蓝桥杯单片机入门(4)—编写代码的主函数框架
    这回,我们要讲的是代码编写的大体框架图中注释写的已经很清楚了,一般情况下,我们在最开始的顶部进行头文件的引入其次,主函数一般是不需要有返回值的,如果需要那就定义成int类型,这里我定义的是void没有返回值的类型的函数。voidmain下面就是代码执行的区域了,while(1)是一个死循环......
  • Oracle_取随机数函数的常用方法
    1、从表中随机取记录SELECT*FROM(SELECT*FROMSDXJ.TEST_01ORDERBYDBMS_RANDOM.random)WHEREROWNUM<5;表示从SDXJ.TEST_01表中随机取4条记录2、产生随机数产生一个任意大小的随机数:SELECTDBMS_RANDOM.RANDOMFROMDUAL;产生......
  • C++ 析构函数注意事项总结
    在C++中,析构函数是一个特殊的成员函数,它在对象生命周期结束时自动调用,用于执行清理工作,如释放分配给对象的内存、关闭文件、断开网络连接等。正确编写析构函数对于防止内存泄漏、资源泄露和其他资源管理问题至关重要。以下是编写C++析构函数时需要注意的一些重要事项:确保资......
  • C++类和对象(下):初始化列表、explicit关键字、友元函数、友元类
    文章目录C++类和对象9、初始化列表9.1构造函数体赋值9.2初始化列表9.3explicit(显示)关键字10、友元10.1友元函数10.2友元类C++类和对象9、初始化列表一个类的构造函数要初始化成员变量有两种方式,一种是构造函数体赋值,另一种是初始化列表。9.1构造函数体赋值......
  • Javascript之函数式编程
    一、是什么函数式编程是一种"编程范式"(programmingparadigm),一种编写程序的方法论主要的编程范式有三种:命令式编程,声明式编程和函数式编程相比命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算......
  • ArrayList元素的删除(4种函数)
    1Clear()方法Clear()方法用来从ArrayList中移除所有元素,语法格式如下。string[]str1={"a","b","c"};ArrayListList=newArrayList(str1);List.Clear();2Remove()方法Remove()方法用来从ArrayList中移除特定对象的第一个......
  • 聚合函数COUNT()用法解析
    在数据分析工作中,我们常用聚合函数COUNT()统计一些特定条件的行数。常用的用法有如下三种:COUN(*)COUNT(1)COUNT(字段)那它们三者的区别在哪里呢。COUNT(*)用来计算表中所有行的数量,包括那些包含NULL值的行。COUNT(1)也用于计算所有行的数量,它也不会忽略任何行。COUNT(字段)......
  • 函数qsort的使用与冒泡排序模拟实现qsort
    目录一.qsort函数的使用示例二.使用冒泡排序模拟实现qsort函数二.1.冒泡排序 二.2.模拟实现qsort函数一.qsort函数的使用1.1.qsort函数是用来排序任意数据类型的数组,对其中的元素进行一定规则的排列2.qsort不返回任何值3.qsort的第一个参数是一个void*指针,指向......
  • C语⾔内存函数
    文章目录1.memcpy使用和模拟实现memcpy的使用:memcpy的模拟实现:2.memmove使用和模拟实现memmove的使用:memmove的模拟实现:3.memset函数的使⽤4.memcmp函数的使用1.memcpy使用和模拟实现void*memcpy(void*destination,constvoid*source,size_tnum);......