为啥在 A 类中声明为友元的函数必须在 B 类中定义为公共函数?
Posted
技术标签:
【中文标题】为啥在 A 类中声明为友元的函数必须在 B 类中定义为公共函数?【英文标题】:Why must a function, declared as friend in Class A, be defined as a public function in Class B?为什么在 A 类中声明为友元的函数必须在 B 类中定义为公共函数? 【发布时间】:2016-08-01 16:49:39 【问题描述】:A 类是 B 类实例的容器。
文件 A.h:
#include "B.h"
Class A
public:
unique_ptr<B> getInstanceOfB();
private:
unique_ptr<map<int, shared_ptr<B>>> uptr_BInstancesMap;
map<string, int> map__BUniqueValues;
friend int B::getValueIndex( const string );
;
文件 B.h:
Class B
public:
unique_ptr<B> returnInstanceOfB();
// int getValueIndex( const string ); // Compiles fine
private:
int int__ValueIndex;
int getValueIndex( const string ); // "error: 'int B::getValueIndex(std::string)' is private"
可能有超过 100,000 个 B 的实例存储在 A 的实例中,但由 B 的这些实例表示的唯一值会少得多。 所以想法是将唯一值存储在 A 的实例中,并将索引存储到 B 的每个实例中的(共享)值。 对于朋友功能来说,这似乎是一个合理的场景。
getValueIndex() 用于 B 类;它不应该公开。 有人能解释一下(也许是一个危险的例子)为什么朋友函数定义不能是私有的吗?
【问题讨论】:
@Mark Ransom:措辞不佳。 “A类是B类的容器”会更准确吗? 好多了。我现在将删除我的评论。 在 A 类中声明friend int B::getValueIndex(const string);
使其能够访问 A 类的私有/受保护成员,而不是相反。
德米特里,这正是我想要的。 B::getValueIndex 将操纵 A::map__BUniqueValues。
【参考方案1】:
这里有一个“循环”。
friend in A 表示声明的函数可以访问 A 的私有部分。
但是要访问该声明,A 本身必须可以访问它,因此 B 必须有 A 作为朋友。
我理解你对“纯粹”的愿望,但 C++ 完全不是一种“纯粹”的语言。如果 A 和 B 密切相关,并且您对它们都负责,那么与其疯狂地声明,不如让它们成为彼此的朋友。
除了他们之外,没有人可以做任何危险的事情,而您已经处于自己的“危险区域”,您已经知道......那么为什么会出现并发症?
【讨论】:
将“朋友 A 类”添加到 B 类就可以了!我还不明白“要访问该声明,A 本身必须可以访问它”,但这是我的猜测:A 类中的友元函数声明告诉编译器 A 想要授予 B::getValueIndex() 访问权限到它的私有成员,但编译器拒绝,因为 B::getValueIndex() 是私有的,A 甚至不允许知道它在那里。将“朋友类 A”添加到 B 类会授予 A 访问 B 的私有成员的权限 - 包括 B::getValueIndex() - 因此编译器现在可以让该函数访问 A 的私有成员。 确切地说:私人超过私人需要双重“有利益的朋友”......;-)【参考方案2】:我的看法:
私有方法应该是可以随意改变的,在类之外没有影响。如果您将B
的私有方法设为A
的朋友,则该私有方法的签名签名不能在不更改A
的情况下更改。
【讨论】:
Arkadiy:但是如果您对 A 的私有成员进行更改(例如重命名),则必须更改 B 中的友元函数。在我看来,使用友元函数隐含地承认需要更改两个类。 没有对方想要的,谁也不能成为对方的“朋友” 当 B 是 A 的朋友时,您承认当 A 的私人成员发生变化时 B 也必须发生变化。但是 - 不是相反。 A 不知道 B 的私有成员。 Arkadiy:我的意图是 B::getValueIndex() 将访问 A 和 B 的私有成员。A 无意访问 B 中的任何内容。但 Dmitri 也这么认为我的代码中一定有一些东西表明 A 将尝试访问 B。是否在函数签名中缺少对 A 实例的引用? 如果您将友元函数设为私有,则根据定义,A 知道 B 的一个私有函数(友元声明中引用的那个)。我认为 C++ 标准编写者认为这是不可取的,所以朋友函数必须是公开的。这是一个非常薄弱的理由,但我现在能想到的最好的理由。以上是关于为啥在 A 类中声明为友元的函数必须在 B 类中定义为公共函数?的主要内容,如果未能解决你的问题,请参考以下文章