33.友元
类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?
解决方法是使用友元函数,友元函数是一种特权函数,c++允许这个特权函数访问私有成员。这一点从现实生活中也可以很好的理解:
比如你的家,有客厅,有你的卧室,那么你的客厅是的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。
程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。
1. 全局函数作友元函数
友元函数的目的:访问类中的私有成员属性
#include
#include
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();
}
运行结果:
可见函数连类型的属性都能够访问,因为加了如下代码使全局函数变成了友元函数:
//让全局函数:好朋友函数 变成友元函数friend void goodfriend(Building* building);
2. 整个类作友元类
所谓的让整个类作为友元类,意思是让某个类成为另一个类的类
#include
#include
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();
}
此时会报错,因为类还不是类的友元类
加上以下添加友元类的代码即可:
//让googfreind类作为Building类的友元类,语法如下:friend class goodfriend;
完整代码:
#include
#include
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
#include
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();
}
运行结果: