C++ 为什么可以';私有成员函数不是另一个类的友元函数吗?
这会导致如下错误: 错误:友元函数“xx”是“x”的私有成员 为什么我不能将私有成员函数声明为另一个类的朋友 朋友声明中指定的姓名应可在 包含友元声明的类的作用域 原因很简单,<代码>私人成员应遵守明确的规则: 类的成员可以是C++ 为什么可以';私有成员函数不是另一个类的友元函数吗?,c++,class,language-lawyer,friend,access-rights,C++,Class,Language Lawyer,Friend,Access Rights,这会导致如下错误: 错误:友元函数“xx”是“x”的私有成员 为什么我不能将私有成员函数声明为另一个类的朋友 朋友声明中指定的姓名应可在 包含友元声明的类的作用域 原因很简单,私人成员应遵守明确的规则: 类的成员可以是 私人;也就是说,它的名称只能由声明它的类的成员和朋友使用 允许在无关类内的声明中命名私有成员将违反此规则:它允许另一个类依赖于实现细节而不被明确允许。例如,当更改私人成员的名称、类型或签名,或将其完全删除时,这会产生问题;这是为了不破坏该类的接口 这可以通过使整个x成为y的朋
;也就是说,它的名称只能由声明它的类的成员和朋友使用私人
x
成为y
的朋友来避免:
class x
{
void xx() {}
};
class y
{
friend void x::xx();
};
.使
x::xx
私有化的想法应该是x::xx
是其他类不应该依赖的实现细节。这不仅仅意味着其他类不能调用x::xx
,它还意味着,或者更确切地说,它应该意味着,例如将x::xx
重命名为x::xy
不应该破坏类本身和类的朋友之外的任何东西
在您的情况下,将x::xx
重命名为x::xy
将导致类y
出错,即使它不是x
的朋友
避免这种情况的一种方法是让y
成为x
的朋友,这样y
就可以访问x
的私人成员。然后它可以将x::xx
声明为朋友
(注意:对于“为什么编译器不允许这样做?”这个问题,更直接的答案是“因为标准不允许这样做”,这自然会引出后续问题“为什么标准不允许这样做?”。我试图回答这个后续问题。)可能重复的@hagubear肯定不是重复的。你是在问为什么语言不允许这样做吗?在某种程度上,有人认为(可以理解)这是个坏主意。因为否则它就不是私有的。我可以拥有一个私有的虚拟成员函数,并在子类中重写。在基类中重命名那个虚拟函数会破坏一些东西,不是吗?`我喜欢你回答什么问题的区别。@Columbo你是对的。这就是“它意味着”和“它应该意味着”之间的区别之一:)顺便说一句,你解决这个问题的方法很奇怪。让整个班级y
成为x
的朋友,以便能够成为x
成员的朋友?为什么要绕道?@Columbo这取决于具体情况。通常,当然,只要让所有的x
成为y
的朋友即可。这是显而易见的解决办法。但是如果x
是一个具有很多功能的大类,而y
是一个很小的助手类,那么交y
和x::xx
朋友远比交所有x
朋友要少。也许我不理解这个问题,但不应该是相反的,也就是说,让y
成为x
的朋友?在您的示例中,y
无法访问x
@IvanSmirnov的私有方法,原始代码片段的目的是允许x
的成员访问y
的私有数据。啊,没错,这不是最直观的事情。谢谢,明白了。@IvanSmirnov你建议的是hvd下面的方法,这似乎是不必要的复杂。
class x {
void xx() {}
};
class y {
friend x;
};