C++——友元

43 阅读2分钟

在 C++中,一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。

但是借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。

友元函数:在函数前面加 friend 关键字,这样就构成了友元函数。友元函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数。

友元的三种实现:

1、全局函数声明为友元函数

#include <iostream>
using namespace std;

class Building {
	//将全局函数goodFriend()声明为友元函数,就可以访问私有成员
	friend void goodFriend(Building* b);
public:
	Building() {
		m_LivingRoom = "客厅";
		m_BedRoom = "卧室";
	}
public:
	string m_LivingRoom;
private:
	string m_BedRoom;
};
//全局函数
void goodFriend(Building* b) {
	cout << "好朋友正在访问" << b->m_LivingRoom << endl;
	cout << "好朋友正在访问" << b->m_BedRoom << endl;  //访问私有成员
}

void test01() {
	Building b;
	goodFriend(&b);
}
int main() {

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

2、类做友元

不仅可以将一个函数声明为一个类的“朋友”,还可以将整个类声明为另一个类的“朋友”,这就是友元类。友元类中的所有成员函数都是另外一个类的友元函数。

例如将类 B 声明为类 A 的友元类,那么类 B 中的所有成员函数都是类 A 的友元函数,可以访问类 A 的所有成员,包括 public、protected、private 属性的。

#include <iostream>
using namespace std;
//类做友元

class Building {
	//GoodFriend声明为Building的友元类,可以访问Building的所有成员
	friend class GoodFriend;
public:
	Building();//声明构造函数,类外实现

public:
	string m_LivingRoom;
private:
	string m_BedRoom;
};

class GoodFriend {
public:
	GoodFriend();
	void visit(); //用来访问Building的成员
	Building * b;
};

//类外实现构造函数
Building::Building() {
	m_LivingRoom = "客厅";
	m_BedRoom = "卧室";
}

GoodFriend::GoodFriend() {
	b = new Building;
}
void GoodFriend::visit() {
	cout << "好朋友正在访问" << b->m_LivingRoom << endl;
	cout << "好朋友正在访问" << b->m_BedRoom << endl;
}

int main() {

	GoodFriend g;
	g.visit();
	system("pause");
	return 0;
}

3、将其他类的成员函数声明为友元函数

#include <iostream>
using namespace std;

class Building; //提前声明Building类

//声明GoodFriend类
class GoodFriend {
public:
	GoodFriend();
	void visit(); //参观函数,用来访问Building的成员
	void visit2(); //参观函数2,不能访问Building的私有成员
private:
	Building* b;
};
//声明Building类
class Building {
	//将GoodFriend类中的成员函数visit()声明为友元函数
	friend void GoodFriend::visit();
public:
	Building();

public:
	string m_LivingRoom;
private:
	string m_BedRoom;
};
//类外实现成员函数
Building::Building() {
	m_LivingRoom = "客厅";
	m_BedRoom = "卧室";
}

GoodFriend::GoodFriend() {
	b = new Building;
}
void GoodFriend::visit() {
	cout << "1好朋友正在访问" << b->m_LivingRoom << endl;
	cout << "1好朋友正在访问" << b->m_BedRoom << endl;
}
void GoodFriend::visit2() {
	cout << "2好朋友正在访问" << b->m_LivingRoom << endl;
	/*cout << "好朋友正在访问" << b->m_BedRoom << endl;*/
}
void test01() {
	GoodFriend g;
	g.visit();
	g.visit2();

}
int main() {

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

注意事项:

  • 将 GoodFriend类声明在Building类前面,这是因为编译器从上到下编译代码,visit() 函数体中用到了 Building类的成员 m_LivingRoom和m_BedRoom,如果提前不知道 Building的具体声明内容,就不能确定 Building类是否拥有该成员(类的声明中指明了类有哪些成员)。
  • 一个函数可以被多个类声明为友元函数,这样就可以访问多个类中的 private 成员。