2010-06-27 1 views
3

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

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

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

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, которая возвращает указатель на значение, там woudln't быть какие-либо проблемы. Что вы можете сказать об этом?

ответ

4

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

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

Для получения дополнительной информации, прочитайте раздел

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

+0

Возможно, вы имеете в виду: operator [] будет создавать значение/объект, а не ключ. Кроме того, ключ не абстрактный. –

 Смежные вопросы

  • Нет связанных вопросов^_^