Pergunta

Estou trabalhando em um pequeno jogo de roguelike e para qualquer objeto/"coisa" que não faz parte do mapa é baseada em uma classe de Xentity. Existem várias classes que dependem disso, como XPlayer, XItem e Xmonster.

Meu problema é que quero converter um ponteiro da Xentity em XItem quando sei que um objeto está no item. O código de amostra que estou usando para pegar um item é esse, é quando uma entidade diferente pega um item em que está de pé.

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's linked list

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

            // Code to link into inventory is here

            break;
        }

        Ent = Ent->MapList;
    }
}

Meu primeiro pensamento foi criar um método em xentidade que se retornasse como um ponteiro XItem, mas cria dependências circulares que não são resolvíveis.

Estou muito perplexo com este. Qualquer ajuda é muito apreciada.

Foi útil?

Solução

Se você conhecer que o XEntity é atualmente e XItem Então você pode usar um elenco estático.

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

No entanto, você deve revisar você projetar e ver se você pode operar na entidade de uma maneira que significa que você não precisa saber qual é o tipo derivado. Se você puder fornecer à classe base uma interface suficientemente rica, poderá eliminar a inspeção do tipo de verificação da bandeira.

Outras dicas

O elenco resolve o problema como outros apontaram:

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

No entanto, acho que você poderia dar um passo atrás e olhar para o design do programa, pois a redução é algo que deve e pode ser evitado por um design adequado para os objetos. Uma ferramenta poderosa, embora um pouco complexa, possa ser o Padrão de visitante.

Kit!Você deve ter um plano de recuperação de desastres no lugar antes da mão, não procurando por um agora!Mas isso se siga as etapas de migração para um novo servidor.

Movendo o SharePoint para novo servidor

A linha oficial da Microsoft neste patch é desinstalar e reinstalar o SharePoint e sempre testar os patches em um servidor de teste antes de se candidatar a viver.

Depois de recuperar passar algum tempo olhando para planos de recuperação de desastres.

Apenas lance:

XItem* Item = (XItem*)Ent;

Uma abordagem melhor, no geral, é a seguinte:

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

    // Code to link into inventory is here

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

if ( Item )
    // do something with item

Para que isso funcione, você precisa ativar o RTTI. Olhar aqui Para maiores informações.

Como foram respondidos, existem 2 operadores:

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

E:

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

o segundo é mais lento, mas mais seguro (verifica se é possível) e pode retornar nulo, mesmo que Ent não é.

Eu tendem a usar os dois embrulhados em um método:

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
}

Dessa forma, recebo verificação do tipo durante o desenvolvimento (com uma exceção se algo correr mal) e recebo velocidade quando terminar. Você pode usar outras estratégias, se desejar, mas devo admitir que eu gosto bem assim :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top