ptr_map и указатель - PullRequest
       46

ptr_map и указатель

3 голосов
/ 27 июня 2010

Я использую ptr_map из boost для хранения объектов, полученных из некоторого базового абстрактного типа.

class Entity { virtual void foo() = 0; };
class Entity1 : public Entity {};
class Entity2 : public Entity {};

boost::ptr_map<string, Entity> someMap; // We could store pointers for abstract type

Вставка прекрасно работает:

someMap.insert("someKey", new Entity1());
someMap.insert("someKey", new Entity2());

Но не возвращается с карты:

template<typename EntityType>
EntityType *GetEntity(const string &entityName)
{
    return dynamic_cast<EntityType*>(&someMap[entityName]);
}

GetEntity<Entity1>(entityName);

Теперь проблема: operator [] из ptr_map возвращает ссылку!Так что в constructur может быть тип вызова из значения.Теперь компилятор завершается ошибкой:

 instantiated from ‘EntityType* EntityManager::GetEntity(const std::string&) [with EntityType = Entity1, std::string = std::basic_string<char>]’
error: cannot allocate an object of abstract type ‘Entity’

Если в ptr_map есть какой-либо метод, который возвращает указатель на значение, проблем не будет.Что вы можете сказать по этому поводу?

1 Ответ

4 голосов
/ 28 июня 2010

Часто забываемый факт заключается в том, что оператор [] будет создавать экземпляр ключа, если он не существует.В вашем случае это проблема, потому что ключ абстрактный.Так что вместо этого используйте at ().То есть

return dynamic_cast<EntityType*>(&someMap.at(entityName));

Для получения дополнительной информации прочитайте раздел «Семантика: поиск»

Кстати, я бы поставил под сомнение ваше решение о разработке, чтобы выставить необработанные указатели, хранящиеся вконтейнер, цель которого - облегчить управление памятью.

...