在对象的不同类型的指针之间切换

时间:2014-06-04 22:48:08

标签: c++ pointers object casting downcast

到目前为止,我一直在使用动态投射。但这伴随着它的优点和缺点。似乎不要过多地使用它是一件好事。我发现,关于这个主题的例子通常与几乎没有差异的类有关。但在我的情况下,"孩子"班级的相似之处很少。

这篇文章中的代码不是来自项目。它仅用于示例。

我正在为游戏制作交易系统,项目中会有更多系统。有许多不同的项目可以做许多不同的事情 - 设备,修改,资源。无论它们有多么不同,它们都有价格,无论它们是什么,都可以将它们全部放入库存中。但这就是相似之处的结束,包括被覆盖的方法。

之后,不同的项目以完全不同的方式使用。起初,不同类型的项目被分类在不同类型的单独指针数组中 - 一个用于设备,一个用于修改,e.t.c。要将某些内容放入库存中,我只使用一种方法 - addToInventory(Item* item)。由于项目必须放在正确的数组中,我使用动态转换 - 我将Item* item转换为(例如)Equipment* equi,因此我可以将它添加到Equipment数组中。我想用同样的方法来做,因为它更直观,否则不同的方法会有类似的代码。

addToInventory(Item* item)
{
    if (item->type == 'e')
    {
        Equipment* newEquip = dynamic_cast<Equipment*>(item);
        equipmentArr.add(newEquip);//thous arrays are dynamic- the reason I needed to make the conversion explained later
    }
    else if (item->type == 'm')
    {
        Modification* newMod = dynamic_cast<Modification*>(item);
        modificationArr.add(newEquip);
    }
    //and so on...
}

稍后我想要对一件设备添加修改 - Weapon::addMod(Modification* mod)。在这个方法中,我使用了仅在Weapon类中找到的其他方法和变量。

addMod (Modification* mod)
{//all are found ONLY in class Weapon
    mod[modCount] = mod; //an array of Modification* pointers
    modCount++;
    calcEfficiency();
}

但是当我想制作一个简单的东西来打印清单时,我要么必须复制粘贴并编辑一些代码来转换数组中的指针,所以我可以用相同的打印方法传递它们,或者复制 - 粘贴并编辑相同的代码进行打印。还有第三种选择 - 使数组成为Item对象的所有指针数组。我尝试了最后一个选项。

它摆脱了addToInventory(Item* item)的投射,耶!但是每当我需要调用诸如Weapon::addMod(Modification* mod)之类的方法以及其他地方时,它都需要使用转换。否则,我需要将方法放在方法中,但我希望方法显式地采用Equipment*参数。

该项目仍处于开发阶段,所以我不知道我可能需要多少使用强制转换,因此我可以在需要时在不同类型的指针之间来回切换。

所以,在类似的情况下,我应该如何在不同类型的指针之间切换?

1 个答案:

答案 0 :(得分:1)

您可能希望将(广义)Equipment实现的特征(即ModificationItem)表示为纯虚拟类(即接口)。这样,对这些接口进行动态转换和动态转换检查就可以了,并且可以降低噪声,以便为EquipmentModification的实际实现进行处理。

另一种方法是使用CRTP patternstatic_cast<Interface*>对接口进行编译时检查。

取决于您的用例哪种方式更合适。根据经验:

  • 主要是静态配置=&gt;在编译时完成
  • 更多动态配置(运行时分配的实例)=&gt;在运行时执行