【问题标题】:friend class : inherited classes are not friend as well?朋友类:继承的类也不是朋友吗?
【发布时间】:2009-01-29 09:27:52
【问题描述】:

在 C++ 中,我有一个 A 类,它是 B 类的朋友。

我看起来 B 的继承类不是 A 类的朋友。

这是 C++ 的限制还是我的错误?

这是一个例子。编译时,“return new Memento”行出现错误:

Memento::Memento : 无法访问在 Memento 中声明的私有成员。

class Originator;

class Memento
{
  friend class Originator;

  Memento() {};

  int m_Data;

public:
  ~Memento() {};
};

class Originator
{
public:
  virtual Memento* createMemento() = 0;
};

class FooOriginator : public Originator
{
public:
  Memento* createMemento()
  {
    return new Memento; // Impossible to access private member of Memento
  }
};

void main()
{
  FooOriginator MyOriginator;
  MyOriginator.createMemento();

}

我当然可以将 FooOriginator 添加为 Memento 的朋友,但是,这意味着我必须将所有 Originator 继承的类添加为 Memento 的朋友,这是我想避免的。

有什么想法吗?

【问题讨论】:

标签: c++ class friend


【解决方案1】:

见:Friend scope in C++
投票完全相同。

I looks like inherited classes of B are not friend of class A.

正确

I this a limitation of C++ or my mistake ?

这是 C++ 的工作方式。我不认为这是一种限制。

【讨论】:

    【解决方案2】:

    友谊不是继承的,您必须明确声明每个朋友关系。 (另见“friendship isn't inherited, transitive, or reciprocal”)

    【讨论】:

      【解决方案3】:

      友谊不是传递或继承的。毕竟,你朋友的朋友可能不是你的朋友,或者你父亲的朋友一般也不是你的朋友。

      【讨论】:

        【解决方案4】:

        friend 指令最初的目的是作为绕过封装机制的一些“漏洞”。

        friend 你必须准确地指定(!),哪些类是你的朋友。友谊不是继承的,因此 FooOriginator 在您的示例中无法访问 Memento

        但理想情况下,在您考虑如何使用 friend 指令解决问题之前,我建议您大致了解一下您的设计并尝试摆脱使用 friend,因为可以看出它与我们所爱的 goto 生活在同一类别中:)

        【讨论】:

        • 我不会说那个朋友和goto一样坏。当您可以使用它来精简公共接口时,它甚至可以改进封装。不过这种情况很少,朋友太多会毁了你的私生活。
        • 朋友还不错。它是在逻辑上由两个或多个属于一起的类组成的组内增强封装,但由于没有(也没有模块级保护),因此不能将其制成模块:相反,您在 C++ 中使用朋友而不是内部或包级保护在java中。
        • 但我认为它也像 goto:goto 也不错。但是在你做其他事情之前,用无穷无尽的条件变量破坏你的代码并用它们弄乱范围之前,你只需使用一个 goto 并保持你的代码干净。我相信,在友谊的原则上也是如此。
        • 但我支持你 gimpf,朋友 - 作为 goto - 应该明智地使用和小心应用。
        【解决方案5】:

        友谊不继承,见http://www.cplusplus.com/doc/tutorial/inheritance.html,从基类继承什么?

        【讨论】:

          猜你喜欢
          • 2012-11-30
          • 1970-01-01
          • 1970-01-01
          • 2016-10-29
          • 1970-01-01
          • 2015-10-21
          • 2011-08-10
          • 2010-09-19
          • 2014-01-09
          相关资源
          最近更新 更多