一般来说,类的私有成员只能在类的内部访问,类外的函数是不能访问它们的,
友元
。但是,可以将一个函数定义为类的友元函数,这时该函数就可以访问该类的私有成员了。
同时,也可以把另一个类B定义为本类A的友元类,这样B类就可以访问A类的任何成员了。
下面来具体讨论友元函数和友元类的概念。
友元之非成员函数
在类的定义中用friend声明了一个外部函数或其他类的成员函数(public和private均可)后,这个外部函数称为类的友元函数。
友元函数声明的基本格式为:
friend 函数原型;
友元函数中可访问类的private成员。
用下面的比喻形容友元函数可能比较恰当,将类比作一个家庭,类的private成员相当于家庭的秘密,一般的外人是不允许探听这些秘密的,只有friend(朋友)才有能力探听这些秘密。
友元之成员函数
A类的成员函数作为B类的友元函数时,必须先定义A类,而不仅仅是声明它。
注意:将其他类的成员函数申明为本类的友元函数后,该友元函数并不能变成本类的成员函数。也就是说,朋友并不能变成家人。
成员形式的友元函数见代码9-5
上述代码中,Line类的成员函数dis(…)的实现必须在类外进行,且必须在Point类的定义之后,
电脑资料
《友元》(https://www.unjs.com)。因为其参数中包含了Point这种类型。Line类的dis()函数本来是不能访问Point.x和Pint.y这种Point类的private成员的,但在Point类中将dis()申明为友元函数后就能访问了。但dis()函数依然不是Point类的成员函数。也就是说,dis()只是Point类的朋友了,可以访问Point类的私有成员变量x和y了。
友元函数的重载
要想使得一组重载函数全部成为类的友元,必须一一声明,否则只有匹配的那个函数会成为类的友元,编译器仍将其他的当成普通函数来处理。
class Exp
{
public:
firend void test(int);
};
void test();
void test(int);
void test(double);
上述代码中,只有“void test(int)”函数是Exp类的友元函数,“void test()”和“void test(double)”函数都只是普通函数。
友元类
类A作为类B的友元时,类A称为友元类。A中的所有成员函数都是B的友元函数,都可以访问B中的所有成员。
A可以在B的public部分或private部分进行声明,方法如下:
friend <类名>; //友元类类名