在什么样的情况下我们会将成员函数声明为“友元函数”?“友元函数”这个违反了面向对象编程中“封装”核心概念的东西到底有什么作用呢?
有时候,友元函数在语法上更好(例如,在类Fred中,友元函数允许将Fred参数放在第二个位置,而成员函数要求它必须是第一个)。另一个很好的使用友元函数的例子是二元中缀算术运算符。例如,如果您想允许aFloat + aComplex,那么aComplex + aComplex应该定义为友元而不是成员(因为成员函数不允许左侧参数提升,因为这会改变作为成员函数调用接收者的对象的类)。
class A
{
private:
int b;
public:
class MemberNotFriend {
public:
static void test() {
A a;
a.b = 0;
}
};
};
void test()
{
A::MemberNotFriend::test();
}
这里有一个简单的具体例子,说明我如何使用友元函数:
我有一个游戏,每个精灵对象都将其信息存储为私有成员,例如X、Y位置。 然而,我希望将游戏对象与渲染分离:游戏对象不需要知道它是如何被渲染的。游戏对象仅存储游戏状态,而这个游戏状态可以以多种不同的方式进行渲染。
因此,游戏对象类有一个友元函数:render()。render()函数在游戏对象类外部实现,但它可以根据需要访问X、Y位置成员来渲染游戏对象。