5

我有一个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对象不可克隆,因此引发了错误。

我的问题是:

  • 为什么我会收到错误消息?(我的怀疑是否接近实际发生的事情?)
  • 我该如何解决这个问题?

为了解决编译错误,我考虑了以下内容,但没有太多 C++ 经验,无法决定哪个更合适:

  1. 删除纯说明符 ( = 0) 所以VectorWrapperBase不再是抽象的
    • 这感觉就像一个黑客,因为VectorWrapperBase不应该被实例化
  2. 使 VectorWrappers 可克隆
    • 这似乎可行,但在我的用例中,只有空容器被分配给顶级地图,因此内部的 VectorWrappersptr_map永远不需要被克隆。因此,可克隆性只是为了安抚编译器而不反映实际使用情况。
  3. 忘记ptr_map并使用std::mapandshared_ptr代替。
    • 我不太喜欢这个解决方案,因为我希望矢量包装器的生命周期与地图的生命周期相关联。我也有点担心(也许是不必要的?)shared_ptr在大量多线程应用程序中广泛使用的潜在开销。
4

1 回答 1

0

该声明

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

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

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

于 2012-05-09T12:04:50.920 回答