33.友元
类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?
解决方法是使用友元函数,友元函数是一种特权函数,c++允许这个特权函数访问私有成员。这一点从现实生活中也可以很好的理解:
比如你的家,有客厅,有你的卧室,那么你的客厅是Public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。
程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。
1. 全局函数作友元函数
友元函数的目的:访问类中的私有成员属性
#include<iostream>
#include<string>
using namespace std;
class Building {
//让全局函数:好朋友函数 变成友元函数
friend void goodfriend(Building* building);
public:
string m_room; //客厅
Building()
{
this->m_Bedroom = "卧室";
this->m_room = "客厅";
}
private:
string m_Bedroom; //卧室
};
//全局函数 好朋友
void goodfriend(Building * building) {
cout << "好朋友正在参观" << building->m_room << endl;
cout << "好朋友正在参观" << building-> m_Bedroom << endl;
}
void test()
{
Building* building = new Building;
goodfriend(building);
}
int main()
{
test();
}
运行结果:
可见goodfriend函数连private类型的属性都能够访问,因为加了如下代码使全局函数变成了友元函数:
//让全局函数:好朋友函数 变成友元函数
friend void goodfriend(Building* building);
2. 整个类作友元类
所谓的让整个类作为友元类,意思是让某个类成为另一个类的friend类
#include<iostream>
#include<string>
using namespace std;
//要在前面先加上这行代码,防止在goodfriend类中声明Building属性时报错
class Building;
class goodfriend {
public:
goodfriend();
void visit();
private:
Building* building;
};
class Building {
public:
string m_room; //客厅
Building()
{
this->m_Bedroom = "卧室";
this->m_room = "客厅";
}
private:
string m_Bedroom; //卧室
};
goodfriend::goodfriend()
{
building = new Building;
}
void goodfriend::visit()
{
cout << "好朋友正在访问" << this->building->m_room << endl;
cout << "好朋友正在访问" << this->building->m_Bedroom << endl;
}
void test()
{
goodfriend gf;
gf.visit();
}
int main()
{
test();
}
此时会报错,因为goodfriend类还不是building类的友元类
加上以下添加友元类的代码即可:
//让googfreind类作为Building类的友元类,语法如下:
friend class goodfriend;
完整代码:
#include<iostream>
#include<string>
using namespace std;
//要在前面先加上这行代码,防止在goodfriend类中声明Building属性时报错
class Building;
class goodfriend {
public:
goodfriend();
void visit();
private:
Building* building;
};
class Building {
//让googfreind类作为Building类的友元类,语法如下:
friend class goodfriend;
public:
string m_room; //客厅
Building()
{
this->m_Bedroom = "卧室";
this->m_room = "客厅";
}
private:
string m_Bedroom; //卧室
};
goodfriend::goodfriend()
{
building = new Building;
}
void goodfriend::visit()
{
cout << "好朋友正在访问" << this->building->m_room << endl;
cout << "好朋友正在访问" << this->building->m_Bedroom << endl;
}
void test()
{
goodfriend gf;
gf.visit();
}
int main()
{
test();
}
[友元类注意]
- 友元关系不能被继承
- 友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友
- 友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友
3.成员函数作友元函数
将成员函数定义为友元函数时一定要注意加上函数的定义域!
#include<iostream>
#include<string>
using namespace std;
class Building;
class goodfriend {
public:
goodfriend();
void visit();
private:
Building* building;
};
class Building {
//将visit函数定义为Building类的友元函数,一定注意前面加函数的定义域goodfriend()
friend void goodfriend::visit();
public:
string m_room; //客厅
Building()
{
this->m_Bedroom = "卧室";
this->m_room = "客厅";
}
private:
string m_Bedroom; //卧室
};
goodfriend::goodfriend()
{
building = new Building;
}
void goodfriend::visit()
{
cout << "好朋友正在访问" << this->building->m_room << endl;
cout << "好朋友正在访问" << this->building->m_Bedroom << endl;
}
void test()
{
goodfriend gf;
gf.visit();
}
int main()
{
test();
}
运行结果: