【问题标题】:Is this an appropriate use of class friendship?这是对阶级友谊的适当使用吗?
【发布时间】:2011-06-15 09:52:10
【问题描述】:

在创建windows父类和子对话框类时,让子类成为父类的朋友以访问其私有数据通常是一个好主意,还是应该使用访问器函数?

【问题讨论】:

  • 当你真的想触碰他们的呃……私人空间时,你就可以让班级成为“朋友”。然而,就像在现实生活中一样,这可能会导致一些相当复杂的不太有趣的情况。如果你开始使用这种方法,请小心。

标签: c++ oop class friend


【解决方案1】:

对朋友的需求很少——通常是当您需要在一个类中重新实现一些深层行为而不重写它以便它们都从单个基类继承或不提供大量 asccessor 时。

我唯一需要它是在 ActiveX 中重写基于 openGL 的渲染器 - 当我需要获取大量低级模型数据,但无法(出于非技术原因)重新实现常见的 ABC 时。

【讨论】:

    【解决方案2】:

    我最近也有类似的情况,想把A类的一些私有成员变量暴露给B类。

    我不想添加公共访问器函数,因为这会将这些成员暴露给所有其他类。

    我不想让 B 成为 A 的朋友,因为这会将 A 的所有私有成员暴露给 B。

    所以我专门为此目的创建了另一个类(A-to-B 私有接口)。它是 A 的朋友,除了访问器函数之外什么都没有:

    class A
    {
        int top_secret; // only A has access to it
        int secret; // only A and B have access to it
        friend struct AToBInterface;
    };
    
    struct AToBInterface
    {
        static int secret(const A& object) {return object.secret;}
    };
    
    class B
    {
        void DoSecretStuff(A& object)
        {
            int secret = AToBInterface::secret(object);
            ...
        }
    };
    

    您可以调整语法(例如,如果您需要读写访问权限),这只是一个想法。我只在代码中的一个地方使用它,所以如果语法有点毛病也没问题。

    【讨论】:

      【解决方案3】:

      恕我直言,几乎从来没有。

      “朋友”通常用于破坏封装,因为它可以允许外部实体访问您的类的私有数据。您几乎从不想这样做 - 通过公共访问器(可以检查有效性)公开“半私有”数据通常比将私有信息公开给另一个类(可能会压倒你)更好/更安全。

      但是,有时您会有一对/一组非常密切相关的类,将它们保持为单独的类是有意义的,但它们需要对实际上不应该与整个世界共享的数据进行低级别访问。这是可以使用“朋友”的地方 - 小心。

      一般来说,尽量限制朋友的范围(例如朋友方法而不是朋友类),以尽量减少允许直接访问私有数据的区域。让它尽可能简单——记住,另一个阅读你的代码的程序员可能会认为“私有”意味着数据是真正私有的,他们可能会被朋友绊倒。此外,您使用的朋友越多,您的设计就越紧密耦合和难以维护。它们可能很有用,但请确保每次使用都有充分的理由。

      【讨论】:

      • friend 几乎与成员函数一样打破封装!
      • 公共访问者很危险,可以锁定实施决策。如果只有一个类需要了解另一个类的内部结构,您最好使用friend。友谊不会打破封装;它只是改变了胶囊的形状。
      • 我同意你们所有人的看法。然而,人们可以很好地使用“朋友”(即将一个“逻辑实体”分解为具有共享数据的几个类)或糟糕地使用(使随机类可以访问内部数据,这确实破坏了封装,并且是维护的噩梦)。要将成员公开,当然应该使其安全公开访问,这比在通常不添加此类保护的情况下交朋友要好得多,因为程序员相信他知道自己是什么正在做。因此,最好谨慎使用“朋友”,仅在正确的解决方案中使用
      • (我第一段的措辞有所改进以反映这一点)
      猜你喜欢
      • 2023-03-06
      • 1970-01-01
      • 2010-10-10
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 2012-12-31
      • 1970-01-01
      相关资源
      最近更新 更多