在 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 成员。