【问题标题】:Is there a way to call multiple inherited overrides of a function?有没有办法调用函数的多个继承覆盖?
【发布时间】:2019-05-06 08:11:38
【问题描述】:

我有一个 Item 基类和几个子类,它们都覆盖了函数“update()”。

class Item {
   virtual void update()
   {
      ;
   }
}

class BomblikeItem: public Item {
   int fuseTimer=10;
   void update()
   {
      fuseTimer--;
      if(fuseTimer==0)
         explode();
   }
}

class HeartlikeItem: public Item {
   void update()
   {
      beat();
   }
}

class RoboticItem: public Item {
   int energy=10;
   void update()
   {
      if(energy==0)
         shutdown();
   }
}

如果我尝试创建一个继承自两个或多个这些类(例如机器人心脏)的新子对象,我会收到一个错误,即在多个基类中找到了 update()。我不想为每种可能的混搭情况覆盖 update(),但我希望能够制作出仍然像所有这些项目一样工作的新项目。

我目前的解决方案是将所有备用的 update() 函数移动到基 Item 类中,并根据当前项是否标记为该类型的类来确定何时调用它,但感觉非常错误 /低效:

class Item {
   ,,,
   void update()
   {
      if(isType(Bomblike))
         Bomblike realForm=this->dynamicCastTo(bomb)
         realForm->fuseTimer--;
         if(realForm->fuseTimer==0)
            realForm->explode();

      if(isType(Heartlike)
         ,,,
      ,,,
   }
}

class BomblikeItem: public Item {
   int fuseTimer=10;
}

,,,

有没有更好的方法来解决这个问题?有没有办法顺序调用单个覆盖函数的所有继承版本,如“update()”?

【问题讨论】:

  • 您应该能够通过在其前面加上类名来指定您正在谈论的update(),例如BomblikeItem::update()HeartlikeItem::update()
  • 您最好 1) 将 update() 函数声明为虚拟函数,2) 将 update() 函数调用从子代传递到其父代,3) 避免像钻石一样的继承。
  • 我认为可以通过将对象转换为相应的类型来实现
  • 也许你真正需要一个事件处理系统?对于这种行为建模,我不建议采用多重继承路线,我认为您会面临很多痛苦。
  • 你没有将update()函数声明为virtual是不是错字?

标签: c++ diamond-problem


【解决方案1】:

您对当前解决方案的看法是正确的,维护/扩展此类代码将很困难。理想情况下,Item 类应该是抽象类,其所有方法都是纯虚拟方法。但如果它解决了您的问题,那么您可能仍然将“更新”作为具有基本实现的虚拟方法。

要处理 Diamond 问题,您可能需要将 Item 作为其派生类的虚拟基类。

class BomblikeItem: virtual public Item 
                    ~~~~~~~
{
    // ... 
}

class HeartlikeItem: virtual public Item 
                     ~~~~~~
{
    // ... 
}

【讨论】:

    猜你喜欢
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    相关资源
    最近更新 更多