C++语言程序设计

友元的使用
类的私有成员只能在类内访问，那么有没有可能让类外的成员访问？其实，在C++中，友元可以访问类的私有成员。友元不是类的成员，但必须在类的内部声明。因为"谁是我的朋友"必须由"我自己决定"。绝对不能允许下面的现象发生：李四说，"嘿，我是张三的朋友"，然后李四就开始使用张三的一切，包括它的私有财产。李四究竟是不是张三的朋友，必须由张三自己说了算。
通过friend关键字，可以把一个全局函数声明为友元，也可以把另一个类中的成员函数，甚至整个类都声明为友元，请看下面的例子：

| 例10-25

class X; //Declaration
class Y
{
void f(X*);
};
class X
{
private:
int i;
public:
void initialize();
friend void g(X*, int); //Global friend
friend void Y::f(X*); //class member friend
friend class Z; //Entire class is a friend
friend void h();
};
void X::initialize()
{
i = 0;
}
void g(X* x, int i)
{
x->i = i;
}
void Y::f(X* x)
{
x->i = 100;
}
class Z
{
private :
int j;
public:
void initialize();
void g(X* x);
};
void Z::initialize()
{
j = 99;
}
void Z::g(X* x)
{
x->i += j;
}
void h()
{
X x;
x.i = 200; //直接数据操作
}
void main()
{
X x;
Z z;
z.g(&x);
}

类Y有一个成员函数f()，它要访问X对象的私有数据成员i，需将Y::f(X*)声明为类X的友元。这里有一个难题，因为C＋＋的编译器要求在使用任一变量之前必须声明，所以，类Y必须在它的成员Y::f(X*)被声明为类X的一个友元之前声明。但声明Y::f(X*)之前，又必须声明类X。
解决的办法是：首先声明类X，但是这个类X的声明并不完整，能行吗？在本例中是可以的，这是由于Y::f(X*)的参数是指向X对象的指针，所以编译器允许在声明Y::f(X*)之前做一个不完全的类型指定。仅仅是告诉编译器，有一个叫X的类。这样，在类X中，Y::f(X*)就可以成功地声明为一个友元函数。
再来看看其它两个友元函数，第一个声明将一个全局函数g()作为一个友元，但g()在这之前并没有定义，这表明friend可以同时声明全局函数和友元。同样，friend可以同时声明类Z及类Z作为类Y的友元。