【问题标题】:Friend Class In C++C++中的朋友类
【发布时间】:2016-04-22 10:25:27
【问题描述】:

这里我不太了解这个概念,或者我是对的......所以让我们在这里举这个“朋友”类的例子:

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

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

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

【问题讨论】:

    标签: c++ friend-class


    【解决方案1】:

    friend 用于当您不想将 getter/setter/internals 暴露给所有人,而只是暴露给单个类时。所以它是一个封装的工具。

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

    正如@nicomp 所说,“这就像给你的亲朋好友一把你家的钥匙,但你不知道他们会用它做什么”。所以friend 类可以无限制地访问它的朋友类的所有内部。这很不幸,但这里的关键(不是双关语)是让类尽可能小,这样就不会成为问题,这也是根据单一职责原则。

    【讨论】:

    • 哎呀,我发现我懒得将它编辑到我的答案中,但如果有人关心,它是 SFML 的Drawable class,它非常巧妙地使用了friend
    【解决方案2】:

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

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

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

    相反,如果只有一些类或函数需要能够更改x,您可以让它们成为A 类的朋友。这限制了只有那些朋友可以访问,而不是给所有人。

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

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

    【讨论】:

    • @MrWonderful 我更新了答案以限定我的陈述,以解释当我说“没有更好”时我指的是限制访问。希望这有助于澄清一些事情。
    • 我认为这听起来好多了(无论如何,对我来说。)谢谢你的点头!
    【解决方案3】:

    不要忘记测试和/或复制...

    Friend 类/方法可以非常成功地用于检查类功能中的中间状态。

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

    【讨论】:

      【解决方案4】:

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

      但是,这些用例很少(希望如此,否则您的 SW 架构可能有问题),我尽量避免它,因为它是最紧密的耦合形式.

      【讨论】:

        猜你喜欢
        • 2010-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-21
        • 1970-01-01
        • 1970-01-01
        • 2012-01-21
        • 1970-01-01
        相关资源
        最近更新 更多