动态创建一个继承的类,使用STD :: MAP使用基类指针访问
Create an inherited class dynamically, access using base class pointer using std::map?
不确定我可以做到这一点。我有问题是[另一个问题]的变体(您可以创建继承类的std ::地图吗?(。
基本上,以下问题的答案是为继承的类创建指针的地图,该类可根据第一个地图条目搜索地图。然后,您调用指针来解决所需的任何虚拟功能。
我已经实现了一个带有几个命令的命令处理器应用程序。地图是:
std::map<string, BaseCmdClass*> cmd_map;
到目前为止都不错。但是,我们正在更新代码,以提供数百个派生的类。我不想在代码开始时在工厂类中创建所有这些,而是想使用过多的内存。
我想在需要时动态构造一个继承的类,然后使用基类指针删除。我想避免使用大案例声明来调用每个构造函数。
有没有一种方法可以创建std::map
或使用另一个可以查找哪个构造函数的STL容器?然后,当我需要派生的构造函数时,我可以查找此地图以查找要调用的正确派生构造函数。
有没有一种方法可以创建一个std ::映射或使用另一个可以查找要调用的构造函数的STL容器?
当然。您不能直接将指针存储到构造函数上,但是您可以将指针存储到调用构造函数的工厂功能中。
using CmdFactory = BaseCmdClass*();
std::map<std::string, CmdFactory*> factory_map;
您可以使用助手模板生成工厂:
template<class T>
BaseCmdClass* factory() {
return new T;
}
您可以添加这样的工厂:
factory_map["Derived1"] = factory<Derived1>;
我想在需要时动态构造一个继承的类,然后使用基类指针删除。我想避免使用大案例声明来调用每个构造函数。
使用基类指针删除就可以了,只要destructor是虚拟的。不需要案例语句。
进一步发展:
,如果您需要状态工厂,则可以使用std::function
而不是功能指针。
我建议从工厂返回std::unique_ptr<BaseCmdClass>
以避免记忆泄漏。
对于较低的内存开销,如果使用整数作为密钥,则可以使用数组而不是地图,但是构造数组的代码必须了解所有孩子。
解决方案之一是为创建者具有平行层次结构:
class BaseCmdClass {
...
};
class BaseCmdCreator;
class BaseCmdFactory {
public:
static BaseCmdFactory &instance();
void registerCreator( const std::string &name, BaseCmdCreator *cr );
...
};
class BaseCmdCreator {
public:
BaseCmdCreator( const std::string &name )
{
BaseCmdFactory::instance().registerCreator( name, this );
}
virtual std::unique_ptr<BaseCmdClass> create() = 0;
};
template<class T>
class CmdCreator : public BaseCmdCreator {
public:
CmdCreator( const std::string &name ) : BaseCmdCreator( name ) {}
virtual std::unique_ptr<BaseCmdClass> create() override
{
return std::make_unique<T>();
}
};
现在如何使用它 - 在.cpp文件中定义特定的cmdClass,您可以创建一个静态对象:
// Class FooCmdClass defined here
namespace {
CmdCreator<FooCmdClass> registerFoo( "FooCmd" );
}
现在,如果您链接了由此创建的对象文件,则将注册您的class FooCmdClass
。您甚至可以通过插件机制进行完全动态的操作。因此,添加新命令不需要基类的任何更改,只将新.cpp文件添加到项目中。
struct BaseCmdClass {
virtual bool do_something() = 0;
virtual ~BaseCmdClass() {}
};
using upCmd = std::unique_ptr<BaseCmdClass>;
using CmdFactory = std::function<upCmd()>;
using Command = std::string;
std::unordered_map<Command, CmdFactory>& command_factories() {
static std::unordered_map<Command, CmdFactory> retval;
return retval;
}
upCmd make_cmd( Command const& cmd ) {
auto mit = command_factories().find(cmd);
if (mit == command_factories().end() || !*mit) return {};
return (*mit)();
}
// in CopyCmd.cpp
struct CopyCmd : BaseCmdClass
bool do_something() override final {
std::cout << "did copy";
};
static auto registered = command_factories().insert(
"copy",
[]{ return std::make_unique<CopyCmd>(); }
);
};
现在,任何人都可以make_cmd("copy")
并通过其BaseCmdClass
的唯一指针获得CopyCmd
的实例。
- 存储在 std::map/std::set 中,与在存储所有数据后对向量进行排序
- 如何在<N>不发生内存泄漏的情况下同时(线程安全)填充 c++11 std::map<std::string,std::bitset*>?
- 无法在 std::map<std::string,std::shared_ptr 中设置值<class>>
- 如何在C++中迭代集合映射(std::map<std::set< char>, int >)?
- 如何初始化结构字段 std::map<std::string, std::string>称为参数
- issue with std::map std::find
- 为什么 std::map< std::map >不释放内存?
- C++ map<std::string> vs map<char *> 性能(我知道,"again?" )
- 确定运行时std::map/std::set的内存使用情况
- 映射上的模板参数无效 std::map< std::string, Stock*> &Stock
- 我的SFINAE检查std::map/std::vector有什么问题
- 使用 std::map<std::string, int> 计算表达式树
- 将数据从两种不同的数据结构插入 std::map <std::string, int> mymap 并通过套接字发送
- 类中的编译器错误,数据类型为 typedef map<std::string,std::p air<std::string,vector<int>>> MapPai
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- 如何填写和访问 std::map<std::p air<enum1, enum2>, funcPtr>?
- 二进制'<':找不到 map<std::string shared_ptr 的运算符<Foo>>
- 如何将 2 个字符* 数组直接映射到 std::map<std::string,std::string>
- C++ std::map<std::string, int> 获取键以特定字符串开头的值
- 从取消引用的迭代器返回 std::map<std::string, int> 时出现巨大的内存泄漏