朋友 Class 在 C++ 中

Friend Class In C++

我不是很理解这个概念,或者我是对的....所以让我们以这个 "friend" class 为例:

class MyClass{
friend class AnotherClass;
private:
       int secret;
}

class AnotherClass{
public:
      void getSecret(MyClass mc){
          return mc.secret;
      }
}

所以是的......在上面的代码中,如果你这样做它实际上会起作用......但一般来说,为什么你不能一直使用 getter 和 setter 而不是朋友 class?朋友class使用的原因是因为"tediousness"吗?

friend 适用于您不想向所有人公开 getters/setters/internals,而只想向单个 class 公开的情况。所以它是一个封装的工具。

例如,如果您在 MyClass 中提供 public getSecret,每个人都可以访问该私有变量,即使他们不应该知道。这打破了封装。 friend 可以解决这个问题,因此只有那些 class 需要了解 secret 的人才能访问它。

正如@nicomp 所说,"it's like giving your physical friend a key to your house but you don't know what they will do with it"。因此 friend class 可以无限制地访问其好友 class 的所有内部结构。这很不幸,但这里的关键(没有双关语意)是保持 classes 尽可能小,这样这就不会成为问题,这也符合单一责任原则。

考虑我最近遇到的以下用例:我将一些代码从一个 class 重构到另一个 class。这个新的 class 必须从原来的 class 访问成员,但我不想通过 public getters 提供这个以避免其他客户弄乱这些。在这种情况下,我真的很欢迎 C++ 友谊机制。

但是,这些用例很少(希望如此,否则您的 SW 体系结构中可能存在问题)并且我尽量避免使用它,因为它是 最严格的形式耦合.

A public gettersetter 允许任何人访问。它们有一些用途,特别是用于在某些 属性 更改时维护 class 不变量,但是看起来像以下代码的 getter / setter 对是 不比 public 成员变量 更好的限制访问:

class A {
 public:
  int getX() const { return x; };
  void setX(int x_) { x = x_; };
 private:
  int x;
};

getX()setX() 函数只提供对 x 的访问。每个人都可以使用它们,因此任何人都可以更改 x 的值。那么将其设为私有是没有意义的。

如果相反,只有 一些 classes 或函数需要能够改变 x,你可以让他们成为 [=37] 的朋友=] A。这限制了只有那些朋友的访问权限,而不是给每个人。

因此,friend 是一种封装工具,允许封装比“只是我自己的 class”(私有成员)或“只是我的 class 和classes 派生自它”(受保护的成员)。友元不需要在同一个 class 层次结构中(它根本不需要是 class;函数可以是友元),但它仍然允许您将访问限制为仅访问那些真正需要它的东西.

请注意,与 getters 和 setters 一样,应谨慎使用。封装是一件好事,在可能的情况下,你的 class 的私有成员应该保持私有。 friend 是一个允许您有选择地授予访问权限的工具,但您应该始终仔细考虑是否需要授予该访问权限,或者需要它的函数/class 是否最好成为成员你的 class,而不是。

不要忘记测试 and/or 复制...

朋友 classes / 方法可以非常成功地用于检查 class 功能中的中间状态。

它们对于某些类型的复制构造函数也很有用,其中要复制的 class 不是目标 class 的直接祖先,因此排除了 protected 成员作为选项。