Sha*_*hin 5 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>());
Run Code Online (Sandbox Code Playgroud)
这似乎有效.但是,当我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()));
Run Code Online (Sandbox Code Playgroud)
最后一行失败了:
/SOMEPATH/boost_1_48_0/boost/ptr_container/clone_allocator.hpp:34
error: cannot allocate an object of abstract type ‘xyz::VectorWrapperBase’
Run Code Online (Sandbox Code Playgroud)
作为C++的新手,这是令人费解的.
我怀疑错误是由于地图插入复制了AgentMemory涉及克隆的对象ptr_map.由于我的VectorWrapper对象不可复制,因此会引发错误.
我的问题是:
为了解决编译错误,我考虑了以下内容,但是没有太多C++经验无法确定哪个更合适:
= 0),因此VectorWrapperBase不再是抽象的
VectorWrapperBase永远不应该被实例化ptr_map永远不会被克隆.因此,克隆性只是为了安抚编译器而不反映实际用法.ptr_map并使用一个std::map而shared_ptr不是.
shared_ptr在大量多线程应用程序中广泛使用的潜在开销,我也有点担心(可能是不必要的?).该声明
agent_map.insert(std::pair<std::string, AgentMemory>(agent_name, AgentMemory()));
Run Code Online (Sandbox Code Playgroud)
将调用 的默认构造函数AgentMemory,后者又将调用 的默认构造函数boost::ptr_map<std::string, VectorWrapperBase>,后者将尝试调用抽象基类的不存在的构造函数VectorWrapperBase。
因此,您必须确保每个包装或继承类型的构造函数VectorWrapperBase都应始终构造一个具体的派生类。在您的情况下,选项 3(指向派生类的共享指针的映射)可能是明智的,但这取决于代码的更大上下文。