映射包含抽象基类的ptr_map的对象

时间:2012-05-09 11:28:02

标签: c++ abstract-class stdmap boost-ptr-container

我有一个boost::ptr_map存储抽象基类(例如VectorWrapperBase)作为值,这允许我将字符串映射到不同类型的矢量。

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 ++经验无法确定哪个更合适:

  1. 删除纯说明符(= 0),使VectorWrapperBase不再是抽象的
    • 这感觉就像是一个黑客,因为VectorWrapperBase永远不应该被实例化
  2. 制作VectorWrappers cloneable
    • This seems to work,但在我的用例中,只有空容器被分配到顶层映射,因此内部ptr_map内的VectorWrappers不需要克隆。因此,克隆性只是为了安抚编译器而不反映实际用法。
  3. 忘记ptr_map并改为使用std::mapshared_ptr
    • 我不太热衷于这个解决方案,因为我希望矢量包装器的生命周期与地图的生命周期相关联。关于在大量多线程应用程序中广泛使用shared_ptr的潜在开销,我也有点担心(可能是不必要的?)。

1 个答案:

答案 0 :(得分:0)

声明

agent_map.insert(std::pair<std::string, AgentMemory>(agent_name, AgentMemory()));

将调用AgentMemory的默认构造函数,后者将调用boost::ptr_map<std::string, VectorWrapperBase>的默认构造函数,它将尝试为抽象基类VectorWrapperBase调用不存在的构造函数

因此,您必须确保包装或继承VectorWrapperBase的每个类型的构造函数都应该始终构造一个具体的派生类。在您的情况下,选项3(派生类的共享指针映射)可能是明智的,但这取决于代码的较大上下文。