Domanda

So I want to test whether my object is a potion or a weapon. How do I do this with typeid (i.e. or anything for that matter)??

I then want to instantiate an object based on this condition. I cannot just say T temp because that would instantiate an abstract base class (i.e. my Item class has a pure virtual function in it).

template <typename T>
void List<T>::Load(std::ifstream & file)
{
//Read the number of elements
file.read(reinterpret_cast<char *>(&mNumberOfNodes), sizeof(int));

//Insert nodes into list

//If object is a potion
    //T * temp = new Potion;

//If object is a weapon
    //T * temp = new Weapon;

for( int i = 0; i < mNumberOfNodes; i++ )
{
    temp->Load(file);
    this->PushFront(&temp);
    mNumberOfNodes--;
    mNumberOfNodes--;
}
}
È stato utile?

Soluzione

I do not recommend using typeid to identify object types in the way you plan on using them. The reason is the values stored in the type information can change between builds. If this happens every data file that was created prior to changing the program will no longer work.

Instead you should define a set of values yourself and associate them with the various object types in your program. the simplest approach is to use an enumeration and a switch/case block to create the objects when you load the file. The example below shows how you might implement your load function using this approach.

enum ObjectType
{
    Potion,
    Sword,
    Condom
};

template <typename T>
void List<T>::Load(std::ifstream & file)
{
    //Read the number of elements
    file.read(reinterpret_cast<char *>(&mNumberOfNodes), sizeof(int));

    //Insert nodes into list

    for( int i = 0; i < mNumberOfNodes; i++ )
    {
        T* obj = NULL;
        int nodeType;

        file.read(reinterpret_cast<char *>(&nodeType), sizeof(nodeType));
        switch(nodeType)
        {
        case Potion:
            obj = new Potion(file);
            break;

        case Sword:
            obj = new Sword(file);
            break;

        case Condom:
            obj = new Trojan(file);
            break;

        default:
            throw std::runtime_error("Invalid object type");
        }

        PushFront(&obj);
    }
}

Depending on your requirements implementing a factory function or class may be more beneficial. This page describes the factory pattern and provides example code (in Java but easily understandable).

Altri suggerimenti

I think typeid is sufficient to do this, this website explains how it works http://www.cplusplus.com/reference/typeinfo/type_info/?kw=type_info

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top