24
class x
{
    void xx() {}
};

class y
{
    friend void x::xx();
};

这会导致类似的错误

错误:友元函数“xx”是“x”的私有成员

为什么我不能将私有成员函数声明为另一个类的朋友?

4

2 回答 2

16

[class.friend]/9 :

由友元声明指定的名称应可在包含友元声明的类范围内访问。

原因很简单;private成员应遵守明确的规则:

一个类的成员可以是

  • private; 也就是说,它的名称只能被声明它的类的成员和朋友使用。

允许在不相关类的声明中命名私有成员将违反此规则:它使另一个类能够依赖于实现细节而没有被明确允许。例如,当更改私有成员的名称、类型或签名,或将其完全删除时,这会成为问题;这是为了不破坏该类的接口。

这可以通过将 的全部x朋友设为 来规避y

class x {
    void xx() {}
};

class y {
    friend x;
};

演示

于 2014-11-16T11:10:18.210 回答
15

制作的想法x::xx private应该x::xx是其他类不应该依赖的实现细节。这不仅仅意味着x::xx不能被其他类调用,它意味着,或者更确切地说,它应该意味着,例如重命名x::xxx::xy应该破坏除了类本身和类的朋友之外的任何东西。

在您的情况下,重命名x::xxx::xy会导致类y出现错误,即使它不是x.

避免这种情况的一种方法是结交y的朋友x,以便y可以访问xprivate成员。然后它可以声明x::xxfriend.

(注:对于“为什么编译器不允许这个?”这个问题更直接的回答是“因为标准不允许这个。”,这自然会引出后续问题“为什么标准不允许这个? “。我正试图回答那个后续问题。)

于 2014-11-16T11:13:11.200 回答