ptr_map and pointer

扶醉桌前 提交于 2019-12-01 06:51:53

问题


I'm using ptr_map from boost for storing objects derived from some base abstract type.

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

Inserting works great:

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

But not returning from map:

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

GetEntity<Entity1>(entityName);

Now the problem: operator[] of ptr_map returns reference! So in constructur there could be calling type from value. Now compiler fails with error:

 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’

If there is any method in ptr_map which returns pointer to the value, there woudln't be any problems. What could you say about this?


回答1:


An oft forgotten fact is that operator[] will instantiate the key if it doesn't exist. This is a problem in your case because the key is abstract. So instead, use at(). That is,

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

For more info, read the "Semantics: lookup" section

BTW, I would question your design decision to expose raw pointers stored within container whose very purpose is to alleviate memory management.



来源:https://stackoverflow.com/questions/3128296/ptr-map-and-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!