我有一个boost::ptr_map
,它将抽象基类(例如VectorWrapperBase)存储为值,这允许我将字符串映射到不同类型的向量。包含抽象基类的ptr_map的映射对象
boost::ptr_map<std::string, VectorWrapperBase> memory_map;
//...
memory_map.insert(str_key, new VectorWrapper<T>());
这似乎工作。但是,当我将memory_map
作为另一个类的成员并尝试将该类存储在std::map
中时,编译失败。
class AgentMemory {
//...
private:
boost::ptr_map<std::string, VectorWrapperBase> memory_map;
};
std::map<std::string, AgentMemory> agent_map;
//...
agent_map.insert(std::pair<std::string, AgentMemory>(agent_name, AgentMemory()));
最后一行失败:
/SOMEPATH/boost_1_48_0/boost/ptr_container/clone_allocator.hpp:34
error: cannot allocate an object of abstract type ‘xyz::VectorWrapperBase’
作为新的C++,这是令人费解。
我嫌疑人错误是地图插入复制AgentMemory
对象,涉及克隆ptr_map
。由于我的VectorWrapper
对象不是cloneable,所以会引发错误。
我的问题是:
- 为什么会出现错误? (我的怀疑是否接近实际发生的事情?)
- 我该如何解决这个问题?
为了解决编译错误,我认为以下,但没有使用C多少经验++不能决定哪个更合适:
- 取出纯符(
= 0
),所以VectorWrapperBase
是不再是抽象的- 这感觉就像一个黑客,因为
VectorWrapperBase
不应该被实例化
- 这感觉就像一个黑客,因为
- 充分利用VectorWrappers cloneable
- This seems to work,但在我的使用情况下,只有空容器被分配到顶层映射,所以内层
ptr_map
内的VectorWrappers不需要被克隆。因此,可克隆性只是为了安抚编译器,并不能反映实际使用情况。
- This seems to work,但在我的使用情况下,只有空容器被分配到顶层映射,所以内层
- 忘记
ptr_map
并使用std::map
和shared_ptr
代替。- 我不喜欢这个解决方案,因为我希望矢量包装的生命周期与地图的生命周期相关联。我也有点担心(可能不必要)?在大量多线程应用程序中广泛使用
shared_ptr
的潜在开销。
- 我不喜欢这个解决方案,因为我希望矢量包装的生命周期与地图的生命周期相关联。我也有点担心(可能不必要)?在大量多线程应用程序中广泛使用
你的抽象基类有一个虚拟析构函数吗? – TemplateRex
是的。 .. –