为啥 PRIVATE 成员函数不能成为另一个类的友元函数?
Posted
技术标签:
【中文标题】为啥 PRIVATE 成员函数不能成为另一个类的友元函数?【英文标题】:Why can't a PRIVATE member function be a friend function of another class?为什么 PRIVATE 成员函数不能成为另一个类的友元函数? 【发布时间】:2015-01-13 09:21:45 【问题描述】:class x
void xx()
;
class y
friend void x::xx();
;
这会导致类似
的错误错误:友元函数“xx”是“x”的私有成员
为什么我不能将私有成员函数声明为另一个类的友元?
【问题讨论】:
Friend declaration in C++ - difference between public and private 的可能重复项 @hagubear 绝对不是那个副本。 您是在问为什么语言不允许这样做吗?在某些时候,有人认为(可以理解)这是一个坏主意。 因为否则它不会是私有的。 【参考方案1】:[class.friend]/9:
朋友声明指定的名称应可在 包含朋友声明的类的范围。
原因很简单; private
会员必须遵守明确的规则:
一个类的成员可以是
private
;也就是说,它的名称只能被声明它的类的成员和朋友使用。
允许在不相关类的声明中命名私有成员将违反此规则:它允许另一个类依赖于实现细节而无需明确允许。例如,当更改私有成员的名称、类型或签名,或完全删除它时,这会成为问题;这是为了不破坏该类的接口。
这可以通过将整个x
设为y
的朋友来规避:
class x
void xx()
;
class y
friend x;
;
Demo.
【讨论】:
可能我没看懂问题,但不应该是相反的方式,就是让y
成为x
的朋友吗?在您的示例中,y
将无法访问 x
的私有方法。
@IvanSmirnov 最初的 sn-p 的意图是允许x
的成员访问y
的私人数据。
啊,对,不是最直观的东西。谢谢,知道了。
@IvanSmirnov 您建议的是 hvd 下面的方法,这似乎是不必要的复杂。【参考方案2】:
制作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
。
(注意:对于“为什么编译器不允许这个?”这个问题更直接的回答是“因为标准不允许这个。”,这自然会引出后续问题“为什么标准不允许这个。”允许这个吗?”。我正在尝试回答这个后续问题。)
【讨论】:
我可以拥有一个私有的虚拟成员函数,并在子类中被覆盖。在基类中重命名该虚函数会破坏某些东西,不是吗?` 我喜欢你所回答的问题究竟的区别。 @Columbo 你是对的。这是“它意味着”和“它应该意味着”之间的区别之一。 :) 顺便说一句。你解决这个问题的方法很奇怪。让整个班级y
成为x
的朋友,以便能够与x
的成员成为朋友?为什么要绕道?
@Columbo 这取决于具体情况。通常,当然,只需将所有 x
设为 y
的朋友即可。这是显而易见的解决方案。但是,如果 x
是一个有很多功能的大类,而 y
是一个小助手类,那么让 y
和 x::xx
成为朋友远比让所有 x
成为朋友更具侵略性。以上是关于为啥 PRIVATE 成员函数不能成为另一个类的友元函数?的主要内容,如果未能解决你的问题,请参考以下文章
c++,类的问题。private类型的是否只有类自己可以使用?与protect类型的有啥区别