为什么PRIVATE成员函数不能成为另一个类的朋友函数?

时间:2014-11-16 10:56:36

标签: c++ class language-lawyer friend access-rights

class x
{
    void xx() {}
};

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

这会导致错误,如

  

错误:朋友功能' xx'是' x'

的私人会员

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

2 个答案:

答案 0 :(得分:14)

制作x::xx private的想法应该是x::xx是其他类不应该依赖的实现细节。它并不仅仅意味着x::xx不能被其他类调用,这意味着,或者更确切地说,它应该意味着,例如将x::xx重命名为x::xy不应该破坏课程本身以及班级朋友以外的任何其他内容。

在您的情况下,将x::xx重命名为x::xy会导致类y出错,即使它不是x的朋友。

避免这种情况的方法是让y成为x的朋友,以便y可以访问x private个成员。然后,它可以将x::xx声明为friend

(注意:更直接的问题答案"为什么编译器不允许这样做?"是"因为标准不允许这样做。",这自然导致后续问题"为什么标准不允许这样做?"。我试图回答后续问题。)

答案 1 :(得分:13)

[class.friend]/9

  

朋友声明提名的名称应在   包含朋友声明的类的范围。

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

  

班级的成员可以是

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

允许在不相关的类中的声明中命名私有成员会违反此规则:它允许另一个类依赖于实现细节而不明确允许。例如,当更改私有成员的名称,类型或签名或完全删除它时,这就成了问题;这不打算打破那个类的界面。

这可以通过让x的朋友成为y的朋友来避免这种情况:

class x {
    void xx() {}
};

class y {
    friend x;
};

Demo