关于c ++:为什么PRIVATE成员函数不能成为另一个类的友元函数?

Why can't a PRIVATE member function be a friend function of another class?

1
2
3
4
5
6
7
8
9
class x
{
    void xx() {}
};

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

这会导致错误

error: friend function 'xx' is a private member of 'x'

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


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

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

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

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


[class.friend] / 9:

A name nominated by a friend declaration shall be accessible in the
scope of the class containing the friend declaration.

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

A member of a class can be

  • private; that is, its name can be used only by members and friends of the class in which it is declared.

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

这可以通过使整个x成为y的朋友来规避:

1
2
3
4
5
6
7
class x {
    void xx() {}
};

class y {
    friend x;
};

演示。