C++——友元

2021/5/10 22:33:20

本文主要是介绍C++——友元,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

    • 1 全局函数做友元
    • 2 类做友元
    • 3 成员函数做友元

生活中你的家有客厅(public),有你的卧室(private)
客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去

但是呢,你也可以允许你的好闺蜜好基友进去。

在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术

友元的目的 就是让一个函数或者类 访问另一个类中的私有成员

友元的关键字为 friend

友元的三种实现

  • 全局函数做友元
  • 类做友元
  • 成员函数做友元

1 全局函数做友元

首先,我们要定义一个房屋类,公共成员变量为客厅,私有成员变量为卧室

class Building
{
	// Building的构造函数,给成员变量赋初值
	Building()
	{
		m_SittingRoom = "客厅";
		m_BedRoom = "卧室";
	}
	
	string m_SittingRoom;	// 客厅

private:

	string m_BedRoom;		// 卧室
};

然后定义一个全局函数 goodGay(),用来访问Building类中的私有成员

void goodGay1(Building *building)
{
	cout << "好基友 全局函数 正在访问:(地址传递) " << building->m_SittingRoom << endl;

	cout << "好基友 全局函数 正在访问:(地址传递) " << building->m_BedRoom << endl;
}

当然也可以用引用传递或者最简单的值传递

void goodGay2(Building &building)
{
	cout << "好基友 全局函数 正在访问:(引用传递) " << building.m_SittingRoom << endl;

	cout << "好基友 全局函数 正在访问:(引用传递) " << building.m_BedRoom << endl;
}

void goodGay3(Building building)
{
	cout << "好基友 全局函数 正在访问:( 值传递 ) " << building.m_SittingRoom << endl;

	cout << "好基友 全局函数 正在访问:( 值传递 ) " << building.m_BedRoom << endl;
}

最后定义一个测试函数test(),实现全局函数做友元访问类的私有成员

void test()
{
	Building building;
	goodGay1(&building);
	goodGay2(building);
	goodGay3(building);
}

但是,现在还不能实现全局函数访问类的私有成员!

关键代码

friend void goodGay1(Building *building);
friend void goodGay2(Building &building);
friend void goodGay3(Building building);

在Building类中声明友元函数,告诉编译器 goodGay全局函数是 Building类 的好朋友,可以访问Building对象的私有成员

class Building
{
	// 告诉编译器 goodGay全局函数是 Building类  的好朋友,可以访问Building对象的私有成员
	friend void goodGay1(Building *building);
	friend void goodGay2(Building &building);
	friend void goodGay3(Building building);

public:

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

private:

	string m_BedRoom;		// 卧室
};

下面给出全局函数做友元访问类的私有成员的完整示例代码

#include <iostream>
#include <string>

using namespace std;

// 房屋类
class Building
{
	// 告诉编译器 goodGay全局函数是 Building类  的好朋友,可以访问Building对象的私有成员
	friend void goodGay1(Building *building);
	friend void goodGay2(Building &building);
	friend void goodGay3(Building building);

public:

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

private:

	string m_BedRoom;		// 卧室
};



//全局函数
void goodGay1(Building *building)
{
	cout << "好基友 全局函数 正在访问:(地址传递) " << building->m_SittingRoom << endl;

	cout << "好基友 全局函数 正在访问:(地址传递) " << building->m_BedRoom << endl;
}

void goodGay2(Building &building)
{
	cout << "好基友 全局函数 正在访问:(引用传递) " << building.m_SittingRoom << endl;

	cout << "好基友 全局函数 正在访问:(引用传递) " << building.m_BedRoom << endl;
}

void goodGay3(Building building)
{
	cout << "好基友 全局函数 正在访问:( 值传递 ) " << building.m_SittingRoom << endl;

	cout << "好基友 全局函数 正在访问:( 值传递 ) " << building.m_BedRoom << endl;
}

void test()
{
	Building building;
	goodGay1(&building);
	goodGay2(building);
	goodGay3(building);
}


int main()
{
	test();
}

输出结果

好基友 全局函数 正在访问:(地址传递) 客厅
好基友 全局函数 正在访问:(地址传递) 卧室
好基友 全局函数 正在访问:(引用传递) 客厅
好基友 全局函数 正在访问:(引用传递) 卧室
好基友 全局函数 正在访问:( 值传递 ) 客厅
好基友 全局函数 正在访问:( 值传递 ) 卧室

2 类做友元

首先,声明一个要访问的私有变量所属的Building类,防止在下面的好GoodGay类中,编译器不认识Building(当然也可以采取先定义Building类,再定义好基友GoodGay类,这样就不用声明Building类了)

class Building;

然后定义一个好基友GoodGay类,声明了一个Building类型的指针变量building。其中,成员函数采用另一种方式:类内声明,类外定义,可以简化类的内容(在全局函数做友元的示例中,采用在类内声明并定义成员函数的方式,两种方式均可)

class GoodGay
{
public:
	//GoodGay的构造函数
	GoodGay();

	void visit();	//参观函数  访问Building中的属性

	Building * building;


private:


};

接着给出Building类的定义

class Building
{
public:
	//Building的构造函数类内声明,在类外定义
	Building();
		
	string m_SittingRoom;	// 客厅
	
private:
	
	string m_BedRoom;		// 卧室

};

下面给出类外定义成员函数,需要注意的是,在类外定义,需要在成员函数加上所在类的作用域(类名::成员函数名()),以便于告诉编译器,该成员函数属于哪个类。

//Building类的构造函数
Building::Building()
{
	m_SittingRoom = "客厅";
	m_BedRoom = "卧室";

	cout << m_SittingRoom << endl;
	cout << m_BedRoom << endl;

}

//GoodGay的构造函数
GoodGay::GoodGay()
{
	// 创建建筑物对象
	building = new Building;	//在堆区开辟一块内存,并赋给building指针

}

//GoodGay的成员函数visit()
void GoodGay::visit()
{
	cout << "好基友类正在访问:" << building->m_SittingRoom << endl;

	cout << "好基友类正在访问:" << building->m_BedRoom << endl;
}

最后定义一个测试函数,实现类做友元访问其他类的私有成员

void test()
{
	GoodGay gg	//定义一个GoodGay类的对象;
	gg.visit();
}

但是,现在还不能实现一个类访问另一个类的私有成员!

关键代码

friend class GoodGay;

在Building类中声明一个友元类,告诉编译器 goodGay类是 Building类 的好朋友,可以访问Building对象的私有成员

class Building
{
	// 告诉编译器,GoodGay类是Building类的好朋友,可以访问Building类的私有成员
	friend class GoodGay;
public:
	
	Building();
		
	string m_SittingRoom;	// 客厅
	
private:
	
	string m_BedRoom;		// 卧室

};

下面给出类做友元实现一个类访问另一个类私有成员的完整示例代码

#include <iostream>
#include <string>

using namespace std;

// 类作友元

class Building;
class GoodGay
{
public:

	GoodGay();

	void visit();	//参观函数  访问Building中的属性

	Building * building;


private:


};

// 房屋类
class Building
{
	// 告诉编译器,GoodGay类是Building类的好朋友,可以访问Building类的私有成员
	friend class GoodGay;
public:
	
	Building();
		
	string m_SittingRoom;	// 客厅
	
private:
	
	string m_BedRoom;		// 卧室
};

// 类外定义成员函数

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

GoodGay::GoodGay()
{
	// 创建建筑物对象
	building = new Building;
}

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

	cout << "好基友GoodGay类正在访问:" << building->m_BedRoom << endl;
}

void test01()
{
	GoodGay gg;
	gg.visit();
}

int main()
{
	test01();

	return 0;
}

输出结果

好基友GoodGay类正在访问:客厅
好基友GoodGay类正在访问:卧室

3 成员函数做友元

类似于类作友元,我们首先声明一个Building类,防止在下面的好GoodGay类中,编译器不认识Building

class Building;

然后定义GoodGay类,同样采用成员函数在类内声明,类外定义的方式。其中定义两个访问函数

  • visit1(),可以 访问Building中的私有成员
  • visit2(),不可以 访问Building中的私有成员
class GoodGay
{
public:

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

	Building *building;

private:

};

下面给出Building类的定义

class Building
{
public:
	Building();

	string m_SittingRoom;	//客厅
	
private:

	string m_BedRoom;		//卧室
};

下面给出类外定义成员函数

//GoodGay类的构造函数
GoodGay::GoodGay()
{
	building = new Building;
}

//GoodGay类的成员函数visit1()
void GoodGay::visit1()
{
	cout << "visit1()函数正在访问:" << building->m_SittingRoom << endl;
	cout << "visit1()函数正在访问:" << building->m_BedRoom << endl;	
}

//GoodGay类的成员函数visit2()
void GoodGay::visit2()
{
	cout << "visit2()函数正在访问:" << building->m_SittingRoom << endl;
	//cout << "visit2()函数正在访问:" << building->m_BedRoom << endl;	//错误!私有属性不可访问
}

//Building类的构造函数
Building::Building()
{
	m_SittingRoom = "客厅";
	m_BedRoom = "卧室";
}

最后用一个测试函数实现成员函数做友元实现对另一个类私有成员的访问

void test()
{
	GoodGay gg;
	
	gg.visit1();

	gg.visit2();
}

输出结果

visit1()函数正在访问:客厅
visit1()函数正在访问:卧室
visit2()函数正在访问:客厅

同样的,现在还没有声明友元,因此类中的成员函数还不能访问另一个类的私有成员

关键代码

friend void GoodGay::visit1();

在Building类中声明一个友元成员函数,告诉编译器 **visit1()**成员函数是 Building类 的好朋友,可以访问Building对象的私有成员

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

public:
	Building();

	string m_SittingRoom;	//客厅
	
private:

	string m_BedRoom;		//卧室
};

下面给出成员函数做友元实现一个类的成员函数访问另一个类私有成员的完整示例代码

#include <iostream>
#include <string>

using namespace std;

class Building;

class GoodGay
{
public:

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

	Building *building;

private:

	
};

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

public:
	Building();

	string m_SittingRoom;	//客厅
private:

	string m_BedRoom;		//卧室
};


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

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

void GoodGay::visit2()
{
	cout << "visit2()函数正在访问:" << building->m_SittingRoom << endl;
	//cout << "visit2()函数正在访问:" << building->m_BedRoom << endl;	//错误!私有属性不可访问
}

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

void test()
{
	GoodGay gg;
	
	gg.visit1();

	gg.visit2();
}

int main()
{
	test();
	
	return 0;
}

输出结果

visit1()函数正在访问:客厅
visit1()函数正在访问:卧室
visit2()函数正在访问:客厅

以上内容是我在学习黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难的学习笔记,方便日后学习使用。



这篇关于C++——友元的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程