在某些情况下,为不是类成员的函数或单独类中的所有函数授予成员级别的访问权会更方便。仅类实现器可以声明其友元。函数或类不能将其自身声明为任何类的友元。在类声明中,使用 friend 关键字和非成员函数名称或其他类,以允许其访问你的类的专用和受保护成员。
语法
friend class-name;
friend function-declarator;
友元声明
如果声明以前未声明的友元函数,则该函数将被导出到封闭非类范围。
友元声明中声明的函数被视为已使用 extern 关键字声明。(有关 extern 的详细信息,请参阅静态存储类说明符。)
尽管具有全局范围的函数可以在其原型之前声明为友元函数,但是成员函数在它们的完整类声明出现前不能声明为友元函数。以下代码演示此失败的原因:
class ForwardDeclared; // Class name is known.
class HasFriends
{
friend int ForwardDeclared::IsAFriend(); // C2039 error expected
};
前面的示例将类名 ForwardDeclared 输入到范围中,但是完整的声明(具体而言,声明函数 IsAFriend 的部分)是未知的。因此,friend 类中的 HasFriends 声明会生成一个错误。
若要声明两个互为友元的类,则必须将整个第二个类指定为第一个类的友元。此限制的原因是该编译器仅在声明第二个类的位置有足够的信息来声明各个友元函数。
注意
尽管整个第二个类必须是第一个类的友元,但是可以选择将第一个类中的哪些函数作为第二个类的友元。
友元函数
friend 函数是一个不为类成员的函数,但它可以访问类的私有和受保护的成员。友元函数不被视为类成员;它们是获得了特殊访问权限的普通外部函数。友元不在类的范围内,除非它们是另一个类的成员,否则不会使用成员选择运算符(. 和 –>)调用它们。 friend 函数由授予访问权限的类声明。可将 friend 声明放置在类声明中的任何位置。它不受访问控制关键字的影响。
以下示例显示 Point 类和友元函数 ChangePrivate。 friend 函数可以访问其接受为参数的 Point 对象的私有数据成员。
// friend_functions.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class Point
{
friend void ChangePrivate( Point & );
public:
Point( void ) : m_i(0) {}
void PrintPrivate( void ){cout << m_i << endl; }
private:
int m_i;
};
void ChangePrivate ( Point &i ) { i.m_i++; }
int main()
{
Point sPoint;
sPoint.PrintPrivate();
ChangePrivate(sPoint);
sPoint.PrintPrivate();
// Output: 0
1
}










