什么时候应该在 C++ 中使用“朋友"?

2021-12-01 00:00:00 oop encapsulation c++ friend

我一直在阅读 C++ FAQ 并且对 friend 声明.我个人从未使用过它,但我对探索该语言很感兴趣.

I have been reading through the C++ FAQ and was curious about the friend declaration. I personally have never used it, however I am interested in exploring the language.

使用 friend 的好例子是什么?

What is a good example of using friend?

阅读 FAQ 多一点我喜欢 << >> 运算符重载和添加为这些类的朋友的想法.但是我不确定这不会破坏封装.这些异常什么时候才能保持在 OOP 的严格范围内?

Reading the FAQ a bit longer I like the idea of the << >> operator overloading and adding as a friend of those classes. However I am not sure how this doesn't break encapsulation. When can these exceptions stay within the strictness that is OOP?

推荐答案

首先 (IMO) 不要听那些说 friend 没有用的人.它是有益的.在许多情况下,您将拥有不打算公开提供的数据或功能的对象.对于具有许多作者的大型代码库尤其如此,他们可能只是表面上熟悉不同领域.

Firstly (IMO) don't listen to people who say friend is not useful. It IS useful. In many situations you will have objects with data or functionality that are not intended to be publicly available. This is particularly true of large codebases with many authors who may only be superficially familiar with different areas.

友元说明符有多种替代方案,但它们通常很麻烦(cpp 级别的具体类/屏蔽类型定义)或不是万无一失的(注释或函数名称约定).

There ARE alternatives to the friend specifier, but often they are cumbersome (cpp-level concrete classes/masked typedefs) or not foolproof (comments or function name conventions).

进入答案;

friend 说明符允许指定的类访问受保护的数据或在发出友元语句的类中的功能.例如在下面的代码中,任何人都可以向孩子询问他们的名字,但只有母亲和孩子可以更改名字.

The friend specifier allows the designated class access to protected data or functionality within the class making the friend statement. For example in the below code anyone may ask a child for their name, but only the mother and the child may change the name.

您可以通过考虑更复杂的类(例如 Window)来进一步了解这个简单的示例.一个 Window 很可能有许多不应公开访问的函数/数据元素,但相关类(例如 WindowManager)需要这些元素.

You can take this simple example further by considering a more complex class such as a Window. Quite likely a Window will have many function/data elements that should not be publicly accessible, but ARE needed by a related class such as a WindowManager.

class Child
{
//Mother class members can access the private parts of class Child.
friend class Mother;

public:

  string name( void );

protected:

  void setName( string newName );
};

相关文章