【问题标题】:Polymorphism makes function inaccessible多态性使函数无法访问
【发布时间】:2011-08-18 15:55:16
【问题描述】:

我有一张Shopables 的地图,里面有这样初始化的东西:

Shopable* something = new Consumable();

Consumable 有一个函数Heal,但 Shopable 没有。对于某些函数参数,我需要将地图保留为Shopable 地图,但是当我尝试这样做时:

consumables[itemName]->Heal(this);

在另一个函数中,它显示“类 'Shopable' 没有成员 'Heal'”。

我怎样才能解决这个问题?

【问题讨论】:

    标签: c++ class function polymorphism


    【解决方案1】:

    多态性只允许对存在于基类中的虚函数进行虚分派。您不能在基类中调用不存在于基类中的函数,因为它可能存在于派生类中。

    此外,您应该真正指的是Shoppable* something = new Consumable();,除非Shoppable 本身只是某些指针类型的typedef。

    【讨论】:

      【解决方案2】:

      要么 dynamic_cast,要么在 Shopable 下创建一个虚拟的 dummy Heal。

      Consumable *con = dynamic_cast<Consumable*>(consumables[itemName]);
      if(con)
          con->Heal();
      //else this shopable is not really a consumable
      

      或者,在 Shopable 下创建一个名为 Heal() 的虚函数,其中没有任何内容。或者在其中带有调试器警告(如 assert(0)),以便您知道它是否被意外调用。或者做一个纯虚拟(virtual void Heal() = 0;),然后你的程序如果被调用就会崩溃。

      【讨论】:

      • 问题是 Shopable 是基类,其他三个东西都继承自它,只有一个可以治愈。使用通用的 OOP 编程标准,是否仍然建议在 Shopable 中放置一个纯虚函数?
      • 好吧。我以前从未使用过它 - 请解释一下它的作用?
      • 它允许您将对象指针从一个类转换到另一个类,确保该对象确实是转换目标类(或派生类)的实例。如果不是,则 dynamic_cast 返回 null。为了让它工作,源类必须至少有一个虚函数。 cppreference.com/wiki/keywords/dynamic_cast
      • 这个例子应该是Consumable* con = dynamic_cast&lt;Consumable*&gt;(consumables[itemName]);吗?
      【解决方案3】:

      Heal 是每个 Shoppable 都应该具备的功能吗?如果是这样,您应该在 Shoppable 中将其声明为 pure virtual function 并在所有子类中实现它。

      【讨论】:

      • @Pig Head:那么您应该考虑将它们放在同一个集合中是否真的是正确的做法。如果您的回答是肯定的,我强烈建议您查看Visitor pattern,它基本上可以让您的 Shoppable 对象确定某个操作是否适用于它们,例如someShoppable->Visit(new HealAction()); Consumables() 中的 Visit() 实现知道 HealAction 并允许该操作执行该操作,而 Shoppable 中的基本实现则不知道,忽略该操作。
      【解决方案4】:

      让 Heal() 在 Shopable 上成为纯虚拟的?

      【讨论】:

        【解决方案5】:

        如果 Heal() 仅适用于从 Consumable 派生的特定类,那么您应该使用 Alekseyev 的使用 dynamic_cast 的解决方案。

        如果尚未启用 RTTI,您将需要启用它,并且对于性能关键代码 dynamic_cast 可能会产生负面影响。

        您可能想看看this site,它解释了 C++ 中 RTTI 的基础知识。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-21
          • 1970-01-01
          • 2016-04-10
          • 2019-09-22
          • 2019-03-24
          • 2021-08-29
          • 2021-12-08
          • 1970-01-01
          相关资源
          最近更新 更多