【问题标题】:Base class with pointer to deriving object: How to tell both of each other's existence?带有指向派生对象的指针的基类:如何判断彼此的存在?
【发布时间】:2016-04-27 20:48:03
【问题描述】:

这是一个最小的例子。我有一个需要知道 Deriving 类的 Base 类。反过来,Deriving 类需要知道 Base 类。那么如何定义它们,让它们知道彼此的存在呢?

class Base {
  Deriving* d;
public:
  Base(Deriving* deriving) {
    d = deriving;
  }
  void f() {
    d->g();
  }
};

class Deriving : public Base {
public:
  Deriving() : Base(this) {}
  g();
};

这是我尝试过的以及编译器所说的: 首先定义Base 导致error: 'Deriving' does not name a type。首先定义Deriving 导致error: expected class-name before '{' token。声明 BaseDeriving 的不完整类型会导致 error: invalid use of incomplete type 'class X'。我不知道还能尝试什么。

非常感谢任何帮助。

【问题讨论】:

  • 为什么它需要知道“Deriving”,为什么不直接取一个指向“Base*”的指针?
  • 因为在我的程序中可能有很多 Base 对象由于某些原因指向同一个 Deriving 对象。
  • object是指实例还是类定义?
  • 您能说明一下您打算如何构建 Deriving 和 Base 吗?
  • 在我的例子中,Base 对象实际上只能由 Deriving 对象构造。 Deriving 对象可以从外部构造。 Deriving 对象具有构造 Base 对象并返回指向它的指针的方法。为什么重要?

标签: c++ oop inheritance circular-dependency


【解决方案1】:

在Base中,只有函数f需要知道类Deriving的定义,所以在定义Deriving之后再定义。

class Deriving;

class Base {
      Deriving* d;
    public:
      Base(Deriving* deriving) {
        d = deriving;
      }
      void f();
};

class Deriving : public Base {
    public:
      Deriving() : Base(this) {}
      void g();
};

void Base::f()
{
    d->g();
}

【讨论】:

    【解决方案2】:

    这种安排通常是逻辑错误。基类永远不需要了解派生类的任何信息。如果基类中的方法需要使用恰好存储在派生类中的资产,则可以将这些资产的引用传递给函数 f()。

    在上面的例子中,期望的行为可以通过继承来实现:

    类似这样的:

    class Base
    {
    public:
      void f() {
        impl_f();
      }
    private:
      virtual void impl_f() = 0;
    };
    
    class Derived : public Base
    {
    private:
      void impl_f() override
      {
        // whatever g() was going to do...
      }
    };
    

    【讨论】:

      猜你喜欢
      • 2021-05-20
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 2021-07-02
      相关资源
      最近更新 更多