Как проверить, к какому производному классу относится ваш объект с typeid?

Итак, я хочу проверить, является ли мой объект зельем или оружием. Как мне сделать это с typeid (т.е. или что-нибудь в этом отношении)??

Затем я хочу создать экземпляр объекта на основе этого условия. Я не могу просто сказать T temp, потому что это создаст экземпляр абстрактного базового класса (т. е. мой класс Item имеет в себе чистую виртуальную функцию).

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--;
}
}

person MrPickle5    schedule 28.05.2013    source источник
comment
Вы ознакомились с фабричным шаблоном?   -  person Captain Obvlious    schedule 28.05.2013
comment
Ха! Я бы хотел иметь. Я сдаю Software Design Patterns в следующем году, но постараюсь понять статью. :(   -  person MrPickle5    schedule 28.05.2013
comment
dynamic_cast — это один из способов.   -  person Vaughn Cato    schedule 28.05.2013
comment
где названия предметов   -  person aaronman    schedule 28.05.2013
comment
Кроме того, поскольку вы используете шаблон, вы можете сделать функцию, которая создает новые объекты, либо параметром шаблона, либо параметром функции, чтобы сама функция не начинала делать предположения об объектах. Для С++ до 11 вы хотели бы взять функторный объект; для С++ 11 вы бы хотели получить std::function.   -  person kfsone    schedule 28.05.2013


Ответы (2)


Я не рекомендую использовать typeid для идентификации типов объектов так, как вы планируете их использовать. Причина в том, что значения, хранящиеся в информации о типе, могут меняться между сборками. Если это произойдет, каждый файл данных, который был создан до изменения программы, больше не будет работать.

Вместо этого вы должны сами определить набор значений и связать их с различными типами объектов в вашей программе. самый простой подход — использовать перечисление и блок переключателей/кейсов для создания объектов при загрузке файла. В приведенном ниже примере показано, как вы можете реализовать функцию загрузки, используя этот подход.

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);
    }
}

В зависимости от ваших требований реализация фабричной функции или класса может быть более полезной. Эта страница описывает шаблон фабрики и предоставляет пример кода (на языке Java, но легко понятном).

person Captain Obvlious    schedule 28.05.2013

Я думаю, что для этого достаточно typeid, на этом веб-сайте объясняется, как это работает http://www.cplusplus.com/reference/typeinfo/type_info/?kw=type_info

person aaronman    schedule 28.05.2013