2016-08-04 8 views
0

アイテムと在庫/装備システムを構築するだけです。どこから始まるか分かりません

これを行うための私の解決策は、より具体的な値とそれらに関連付けられた機能を持つ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 :: ...は、アイテムのサブクラスを識別するために使用しているものです。できるだけ単純

、可能な限り説明:私が探しているソリューションの種類については

。私はペーストをコピーしないことを学びたい!ありがとうございました!

+0

最初にキャストダウンしてから、サブクラスフィールドにアクセスする必要があります。現在、どのクラスに適合しているかをテストしています。キャストしません。 –

+1

*手動でMeleeWeaponに動的にキャストできる場所がありましたが、それを使って遊んだり、もっと混乱しているエラーを繰り返したりしていました。何を試してみましたか? – Ryan

+1

'Item'を使用することを知っていれば、アイテムに' isOneHanded'がないのはなぜですか?実際、はるかに優れた設計は、 'subClass'メンバを使って、何かが何かであると言って、スイッチをオンにすることではありません。 Itemに仮想 'equip'メソッドを持たず、実際のアイテムタイプに応じて必要なものを返すのはなぜでしょうか? – doctorlove

答えて

0

実際のタイプにitemをキャストしなければなりません。そのためには、dynamic_castを使用してください。 dynamic_castは、を実数型に変換することを実行時にチェックします。 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を使用する場合は、あなたもして、動的キャストを行う行置き換えることができます:あなたはアイテムがタイプMeleeWeaponであることを100%確信している場合

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

は、あなたがアップキャストを使用することができますが。 それ以外の場合は、この問題を解決するために動的キャストを使用できます。

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. 
} 
0

あなたはItemを取る機能を持っており、そのItemの種類(およびその他の属性)に応じて、unsigned intを返すようにしたいです。

あなたはdynamic_castを使用することができますがItem(および他の回答で提案)を継承MeleeWeapon(およびその他の項目)を提供します。

私にとっては、スイッチではなく多型を使用する方が理にかなっています。

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(); 
} 
関連する問題