在什么样的情况下我们会将成员函数声明为“朋友函数”?具体目的是什么'朋友函数'违背了OOP服务的'封装'的核心概念之一?
答案 0 :(得分:2)
您将使用友元函数的原因与您使用友元类的原因相同,但是基于成员函数(而不是整个类)。一些很好的解释在this thread。
虽然友元函数和类确实违反了封装,但在某些情况下它们可能很有用。例如,您可能希望允许测试工具访问类内部,以允许您进行白盒测试。您可以打开一个访问测试工具所需内部的特定功能,而不是将整个类打开到测试工具中。虽然这仍然违反了封装,但它比打开整个课程的风险要小。
另请参阅this article以获取有关朋友类和函数的更多信息。
答案 1 :(得分:2)
当您尝试构建必须物理跨越多个C ++类或函数的抽象或接口时,Friend函数和类不会违反封装!这就是朋友被发明的原因。
这些类型的案例并不常见,但有时您被迫使用不同的类和函数实现抽象或接口。经典的例子是实现某种类型的复数类。非成员运算符函数与主复数类具有友谊。
我还记得在用C ++编写CORBA时这样做。 CORBA强迫我有单独的类来实现CORBA服务。但是对于我们软件的特定部分,我需要将它们作为一个接口结合在一起。友谊允许这两个类一起工作,为我们软件的一部分提供无缝服务。
能够将另一个班级上的特定成员函数标记为你班级的朋友可能看起来更奇怪,但这只是一种严格控制友谊的方式。您只允许其中一个成员函数访问,而不是允许整个其他类“in”作为您的朋友。同样,这并不常见,但非常在您需要时非常有用。
答案 2 :(得分:1)
有时朋友在语法上更好(例如,在Fred类中,朋友函数允许Fred参数为秒,而成员要求它是第一个)。友元函数的另一个好用途是二进制中缀算术运算符。例如,如果你想允许aFloat + aComplex,aComplex + aComplex应该被定义为朋友而不是成员(成员函数不允许提升左手参数,因为这会改变对象的类,即成员函数调用的接收者。)
答案 3 :(得分:0)
有时,公共/私人/受保护的保护级别对于现实世界的情况来说还不够。因此,我们提供了一个小型的get-out子句,有助于无需公开方法。
我个人使用它的方式与Java使用“Package”保护级别的方式相同 如果我在同一个包中需要访问的类,我会考虑使用朋友。如果它是另一个包中的类,那么我会想知道为什么这个其他类需要访问并查看我的设计。
答案 4 :(得分:0)
我发现相关的一点:成员类可以访问包含类的私有部分。这有时可能是“朋友”的更好选择。
class A
{
private:
int b;
public:
class MemberNotFriend {
public:
static void test() {
A a;
a.b = 0;
}
};
};
void test()
{
A::MemberNotFriend::test();
}
答案 5 :(得分:0)
以下是我如何使用友元函数的简单具体示例:
我有一个游戏,其中每个精灵对象将其信息存储为X,Y位置作为私人成员。 但是,我希望将游戏对象与渲染分开:游戏对象不需要详细说明渲染方式。游戏对象仅存储游戏状态,并且可以以多种不同方式呈现该游戏状态。
因此游戏对象类有一个友元函数:render()。 render()函数在游戏对象类之外实现,但它可以根据需要访问X,Y位置位置元素来渲染游戏对象。