所以只需建立一个物品和库存/装备系统。
我这样做的解决方案是拥有一个基础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行,这是因为item没有isOneHanded,但是MeleeWeapon没有。这在运行时是安全的99.9999%肯定,但编译器不知道。我在某个地方看到你可以动态地将它动态地投射到MeleeWeapon上,然后我玩了它,得到了更多令人困惑的错误,并且一直持续。
SC :: ...正是我用来识别项目的子类的。
至于我正在寻找的解决方案类型:
尽可能简单,尽可能多的解释。我想学习不复制粘贴!谢谢!
答案 0 :(得分:0)
您必须将item
转换为实际类型。为此,请使用dynamic_cast
。 dynamic_cast
检查运行时是否允许您将item
转换为实际类型。如果item
可以转换为你想要的,它返回一个正确的指针,如果没有,它返回空指针(如果是动态转换指针 - 在引用转换的情况下,它会抛出异常)。它只适用于虚拟类。
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);
答案 1 :(得分:0)
如果你100%确定Item是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.
}
答案 2 :(得分:0)
您有一个Item
函数,并希望返回unsigned int
,具体取决于Item
的类型(和其他属性)。
您可以使用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();
}