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

时间:2009-07-07 17:21:08

标签: c++ function friend

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

这是什么意思?..

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

10 个答案:

答案 0 :(得分:25)

来自C++ FAQ的引用我认为很好地描述了与朋友和封装的情况。

  

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

     

你经常需要在两半的时候将一个班级分成两半   不同数量的实例或   不同的生命周期。在这些情况下,   这两半通常需要直接   相互接触(两半)   曾经是同一个班级,所以你   没有增加代码量   需要直接访问数据   结构体;你只是改组了   代码分为两类而不是   一)。实现这一目标的最安全的方法   是让两半的朋友   彼此。

     

如果您使用刚刚描述的朋友,您将保留私人物品   私人的。不懂的人   这往往是天真的努力避免   在类似的情况下使用友谊   以上,往往他们实际上   破坏封装。他们要么使用   公共数据(怪诞!),或者他们做的   两半之间可以访问的数据   通过public get()和set()成员   功能。有一个公共get()和   set()成员函数为私有   datum只有在私有时才可以   数据从外部“有意义”   class(从用户的角度来看)。在   很多情况下,这些是get()/ set()成员   功能几乎和公众一样糟糕   数据:它们隐藏(仅)的名称   私人数据,但他们不隐藏   存在私人数据。

答案 1 :(得分:17)

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

我个人认为朋友不会打破封锁,因为课程不应该完全依赖,而是相互依赖。

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

然而,机械师课程肯定需要了解汽车的具体内部工作原理,但将机械师制造成汽车是没有意义的。

这是朋友进来的地方。你让机械师成为引擎,刹车或其他需要修理的朋友,他可以修理它。如果能做的就是按气/制动器,他就无法修复它。

答案 2 :(得分:9)

封装意味着无法查看内部内容,friend表示您可以查看内部内容。因此,根据您的观点,friend要么打破封装(通过让朋友看到内部),要么扩展它(通过让开发人员放宽对特定朋友的障碍)。< / p>

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

答案 3 :(得分:7)

我发布了来自Stroustrup的The Design and Evolution of C++的片段,

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

  

友情宣言被视为一个   机制类似于一个机制   保护域授予权   对另一个人的读写能力。它   是一个明确和具体的部分   班级宣言。因此,我   从来没有见过   反复出现friend的断言   声明“违反封装”   除了组合之外的任何东西   对非C ++的无知和困惑   术语

答案 4 :(得分:3)

你有两种不同的思想流派。

第一个(Java&amp; C#...)::抛出类的公共区域中的每个函数,无论该函数是否“需要”访问“私有”区域。

第二个(C ++ ...)::提供“仅”所需的函数,以便这个类可以存活,并在创建类型的不相关集合中提供更高级别的函数。

IMHO :: C ++清楚地满足OOP目标。

答案 5 :(得分:3)

答案 6 :(得分:0)

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

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

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

Friendship and Inheritance

答案 7 :(得分:0)

一旦声明了友元函数,访问说明符,因此,您的类的封装细节将可由该朋友函数访问,该函数不是您的类的一部分/方法。因此,您基本上将对内部数据结构和方法的一些控制委托给您“信任”的外部函数

答案 8 :(得分:0)

友谊以牺牲一些封装为代价促进凝聚力。你仍然有一个封装的单元(类和它的朋友),虽然它不那么精细。但是当替代方法是在类中添加额外的功能时,这并不一定属于,使用友谊可以让您在保持类的凝聚力的同时获得所需的访问权限。封装不是OOP的唯一,甚至是最重要的原则。

答案 9 :(得分:-2)

如果围绕可以访问私有数据的每个人划一条线,那就是封装数据的范围。

如果您使用friend关键字,则必须围绕更多内容绘制该行。因此,根据您的观点,封装会被延长或破坏。

一般来说,我不鼓励使用friend。而是考虑为私人数据添加访问者。