friend关键字(Class/Function)如何在C++中打破封装?

18 c++ function friend

一些程序员说,"朋友功能打破了C++中的封装".一些程序员还说,"朋友的功能不会破坏封装;相反,他们自然会扩展封装屏障"

这是什么意思?..

如果朋友函数打破了C++中的封装,那么如何?

Nav*_*een 25

引用C++常见问题解答,我认为很好地描述了与朋友的情况和封装.

没有!如果使用得当,它们会增强封装效果.

当两个部分具有不同数量的实例或不同的生命周期时,您经常需要将一个类分成两半.在这些情况下,这两个半部分通常需要直接相互访问(这两个部分曾经在同一个类中,因此您没有增加需要直接访问数据结构的代码量;您只需重新调整代码分为两类而不是一类).实现这一目标的最安全的方法是让两半成为彼此的朋友.

如果您使用刚刚描述的朋友,您将保密私人物品.不理解这种情况的人经常做出天真的努力以避免在上述情况下使用友谊,并且通常他们实际上破坏了封装.它们要么使用公共数据(怪诞!),要么通过公共get()和set()成员函数使数据在两半之间可访问.只有当私有数据从类外部"有意义"时(从用户的角度来看),拥有私有数据的公共get()和set()成员函数才是正常的.在许多情况下,这些get()/ set()成员函数几乎与公共数据一样糟糕:它们隐藏(仅)私有数据的名称,但它们并不隐藏私有数据的存在.


Cod*_*ile 17

有些人说"朋友"打破封装的原因是因为封装数据和功能的全部意义在于没有其他任何需要查看数据的内容,但是朋友们让其他类看到内部.

我个人认为朋友们不会破坏包围,因为课程不应该完全依赖,而是相互依赖.

以汽车为例.我们通常使用它作为抽象模型,说我们不需要知道发动机是如何工作的,知道推动油门踏板就可以了.这是封装的整个概念,其中只有我们需要与类交互的函数才是我们需要了解的唯一函数.

然而,机械师类肯定需要了解汽车的具体内部工作原理,但将机械师构建成汽车是没有意义的.

这就是朋友进来的地方.你让机械师成为引擎,刹车或其他任何需要修理的朋友,他可以解决它.如果他所能做的只是压气/刹车,他无法修复它.


Chr*_*isW 9

封装意味着您无法看到内部的内容,这friend意味着您可以看到内部.因此,根据您的观点,friend要么打破封装(通过让朋友看到内部),要么扩展封装(通过让开发人员放松对特定朋友的障碍).

FWIW,一个好的经验法则是说只应该将嵌套/内部类声明为朋友; 这个规则可以概括为"没有长途朋友",即类的朋友(如果有的话)应该在与类本身相同的头文件中声明.

  • 有趣的是,在Ada中,这是获得该功能的唯一方式.他们被称为"孩子".他们遇到的问题是任何人都可以在事后创造一个孩子,即使设计师不打算让他们这样做.所以我们在Ada中使用类似的经验来防止滥用是"没有混蛋的孩子".:-) (2认同)
  • +1为“观点”。许多程序员未能意识到观点的差异。 (2认同)

Nic*_*kis 7

我发布了一篇来自Stroustrup的C++设计和演变的片段,

2.10保护模型,pg.53.
[...]

友情声明被视为一种类似于一个保护域的机制,它为另一个保护域授予读写能力.它是类声明的明确且特定的部分.因此,我从来没有能够看到一个friend 声明"违反封装" 的重复断言,除了无知和混淆与非C++术语的结合.


Jam*_*son 0

friend 关键字允许其他类访问 C++ 中的私有和受保护的数据成员。有些人认为这破坏了封装,其他人认为它将封装扩展到需要访问私有/受保护数据的少数外部类。“破坏封装”意味着成员和方法通常出于某种原因是私有的,而friend关键字破坏了这种封装。

在代码中我看到friend关键字通常会破坏封装并降低代码质量,但偶尔也有使用得好的情况。

如果您以前从未见过,这里有一个关于类友谊和继承的简单教程:

友谊与传承