Converting a pointer for a base class to an inherited class

I am working on a small rogueling game, and for any object / "thing" that is not part of the map, it is based on the XEntity class. Several classes depend on it, such as XPlayer, XItem and XMonster.

My problem is that I want to convert a pointer from XEntity to XItem when I know that the object is in an element. An example of the code that I use to pick up an element is when another object takes the item that it is worth.

void XEntity::PickupItem()
{
    XEntity *Ent = MapList; // Start of a linked list

    while(true)
    {
        if(Ent == NULL) { break; }

        if(Ent->Flags & ENT_ITEM)
        {
            Ent->RemoveEntity(); // Unlink from the map linked list

            XItem *Item = Ent // Problem is here, type-safety

            // Code to link into inventory is here

            break;
        }

        Ent = Ent->MapList;
    }
}

My first thought was to create a method in XEntity that returns itself as an XItem pointer, but it creates circular dependencies that are unsolvable.

I am very fixated on this. Any help is appreciated.

+3
6

, XEntity actull XItem, .

XItem* Item = static_cast<XItem *>(Ent);

, , , . , .

+7

, :

// dynamic_cast validates that the cast is possible. It requires RTTI 
// (runtime type identification) to work. It will return NULL if the 
// cast is not possible.
XItem* Item = dynamic_cast<XItem*>(Ent);
if(Item)
{
    // Do whatever you want with the Item.
}
else
{
    // Possibly error handling code as Ent is not an Item.
}

, , - , - . , , .

+3

, "" . . -, , . "" , . , , , , , .

- . , , . , , , , .

, , ; " ". , , . , , , ... , ( ) .

- . , - . , .

, , . , , , WidgetX , () WidgetY WidgetZ, . / PITA. .

" ". , .

, , boost:: polymorphic_downcast. . . , .

, , - LSP. "if (widget- > type() == type1) {downcast...} else if (widget- > type() == type2)...", , . , . , , , , .

+2
XItem * Item = dynamic_cast< XItem * >( Ent );

if ( Item )
    // do something with item

, RTTI. .

+1

:

XItem* Item = (XItem*)Ent;

, , :

if (XItem *Item = dynamic_cast<XItem*>(Ent)) {
    Ent->RemoveEntity();

    // Code to link into inventory is here

    break;
}
+1

, 2 :

XItem* Item = static_cast<XItem*>(Ent);

XItem* Item = dynamic_cast<XItem*>(Ent);

, ( , ) null, Ent .

:

template <class T, class U>
T* my_cast(U* item)
{
#ifdef _NDEBUG_
  if (item) return &dynamic_cast<T&>(*item); // throw std::bad_cast
  else return 0;
#else
  return static_cast<T*>(item);
#endif
}

, ( , - ), , . , , , :)

+1

Source: https://habr.com/ru/post/1738675/


All Articles