类可以允许其它类或者函数访问它的非共有成员,方法是令其他类或者函数成为它的友元。如果一个类想把某个函数作为它的友元,只需要把friend关键字放在函数声明语句前即可。
友元函数的声明只能出现在类定义的内部,但是在类中出现的具体位置不限。一般来说最好在类定义的开始或者结束前的位置集中声明友元。
友元的声明仅仅指定了访问的权限,而非一个通常意义上的函数声明。如果我们希望类的用户能够调用某个友元函数,那么我们就必须在友元声明之外再专门对函数进行一次声明。
类之间的友元关系
类还可以把其它类(之前已经定义过的)定义成友元。
加入有A、B两个类。类A中的某些成员函数可能需要访问并处理B类的内部数据。这时B类就要把A类指定位它的友元。
class B
{
//A的成员函数可以访问B内的私有部分
friend class A;
}
如果一个类指定了友元类,则友元类的成员函数可以访问此类包括非公有成员在内的所有成员。但是需要注意的是,友元关系不具备传递性,也就是说A有自己的友元,那么A的友元不一定是B的友元。也就是说:每个类负责控制自己的友元类或者友元函数。
令成员函数作为友元
类B 除了把 整个类 A都作为友元之外。也可以把类A中的某个成员函数 action_1作为友元。当把一个成员函数声明成友元时,我们必须明确指出该成员函数属于哪个类。
class B
{
//A::action_1必须在B类之前被声明
friend void A::action_1();
}
要想令某个成员函数作为友元,我们必须仔细组织程序的结构以满足声明和定义彼此之间的依赖关系。
- 首先定义A类,其中声明action_1函数,但是不能定义它。在action_1操作B的成员函数之前,必须先声明B类
- 接下来定义B类,包括对于action_1的友元声明
- 最后定义action_1,此时它才可以使用B的成员
尽管重载函数的名字相同,但他们本质上是不同的函数。因此如果一个类想把一组重载函数声明为它的友元,它需要对这组函数中的每一个分别声明。
类和非成员函数的声明不是必须在它们的友元声明之前。当一个名字第一次出现在一个友元声明中时,我们隐式地假定该名字在当前作用域中是可见的。然而友元不一定真的声明在当前作用域中。