不知道从哪里开始

Not sure where to start with this

本文关键字:开始 不知道      更新时间:2023-10-16

所以只是建立一个物品和库存/装备系统。

我这样做的解决方案是有一个基本的Item类,然后是MeleeWeapon、RangedWeapon等子类,这些子类将附加更具体的值和函数。

我的问题在这里:

unsigned int Player::equipItem(Item item)
{
    //first, we equip the item
    switch (item.subClass) {
    case SC::MELEE_WEAPON :
        if (item.isOneHanded) {
            //unequip mainhand (returns 2! so we can see if something was already there, equip mainhand slot.
            //blabla
            return 1; // yay!
        }
        break;
    case SC::RANGED_WEAPON :
        break;
    case SC::SHIELD :
        break;
    case SC::ARMOR :
        break;
    }
    return 0; //somethings fucked up.
}

所以,错误是第6行,这是因为物品没有isOneHanded,但MeleeWeapon有。这在运行时是安全的,我有99.9999%的把握,但编译器不知道。我在某个地方看到了你可以手动动态地将其投射到MeleeWeapon,我玩了这个,得到了更多令人困惑的错误,等等

SC::。。。正是我用来识别项目是什么子类的。

至于我正在寻找的解决方案:

尽可能简单和尽可能多的解释。我要学的不是复制粘贴!非常感谢。

如果你100%确定物品是MeleeWeapon类型,那么你可以使用upcast。或者,您可以使用动态强制转换来解决此问题。

unsigned int Player::equipItem(Item item)
{
    //first, we equip the item
    switch (item.subClass) {
    case SC::MELEE_WEAPON :
        MeleeWeapon * weapon = dynamic_cast<MeleeWeapon *>(&item);
        if(weapon != nullptr)
        {
          if (weapon->isOneHanded) {
               //unequip mainhand (returns 2! so we can see if something was already there, equip mainhand slot.
            //blabla
            return 1; // yay!
          }
        }
        else //this item is not a MeleeWeapon 
        {
        }
        break;
    case SC::RANGED_WEAPON :
        break;
    case SC::SHIELD :
        break;
    case SC::ARMOR :
        break;
    }
    return 0; //somethings fucked up.
}

您必须将item强制转换为实数类型。为此,请使用dynamic_castdynamic_cast在运行时检查是否允许将item转换为真实类型。如果item可以转换为您想要的内容,它将返回一个正确的指针,如果不能,则返回null指针(在动态强制转换指针的情况下-在引用强制转换的情况下,它将抛出一个异常)。它只适用于虚拟类。

case SC::MELEE_WEAPON :
{ // Brace are required here to allow declaration of local melee
    MeleeWeapon * melee = dynamic_cast<MeleeWeapon *>(&item);
    if (melee) // If cast has succeed
    {
        if (melee.isOneHanded) {
            //unequip mainhand (returns 2! so we can see if something was already there, equip mainhand slot.
            //blabla
            return 1; // yay!
        }
    }
    break;
}
case SC::RANGED_WEAPON :
{
    RangedWeapon * ranged = dynamic_cast<RangedWeapon *>(&item);
    if (ranged) // If cast has succeed
    {
    break;
}
//.... and so on

如果你使用C++11,你也可以用替换做动态投射的行

auto melee = dynamic_cast<MeleeWeapon *>(&item);

您有一个接受Item的函数,并希望根据该Item的类型(和其他属性)返回unsigned int

您可以使用dynamic_cast,前提是MeleeWeapon(和其他项目)继承自Item(并由其他答案建议)。

对我来说,使用多态性比切换更有意义。

class Item
{
public:
    virtual ~Item() = 0;//don't forget this
    virtual unsigned int equip() const
    {
        return 0;
    }
};
class MeleeWeapon : public Item //you do have this already, right?
{
public:
    MeleeWeapon(bool oneHanded) : oneHanded(oneHanded) 
    {
    }
    virtual unsigned int equip() const
    {
        return oneHanded ? 1 : 0;
    }
private:
    bool oneHanded;
};
class Player
{
public:
    unsigned int equipItem(const Item & item);//note the signature change
};
unsigned int Player::equipItem(const Item & item)
{
    return item.equip();
}