什么时候在C ++中使用“friend”?

什么时候在C ++中使用“friend”?

问题描述:

我一直在阅读 C ++常见问题,对于 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

编辑:

阅读常见问题解答更多我喜欢<< code> >> 运算符重载并添加为这些类的朋友。但我不知道如何这不打破封装。

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)不要听那些说朋友的人是没有用的。它是有用的。在许多情况下,您将拥有不打算公开提供的数据或功能的对象。这对于许多作者可能只表面地熟悉不同领域的大代码库尤其如此。

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级别的具体类/蒙面的typedef)或者不是万无一失的(注释或函数名称约定)。

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说明符允许指定的类访问受保护的数据或类中的功能,从而构成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.

您可以通过考虑一个更复杂的类,如窗口,进一步采取这个简单的例子。很可能一个窗口将有许多不应该被公开访问的函数/数据元素,但是一个相关的类如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 );
};