我使用新的C ++ 11功能构建了工厂模式。为此,在注册表中注册了std :: function。现在我正在尝试实现实例化部分。现在它实现如下:
std::map<uint32_t, std::function<Class*()>>::iterator it = m_creators.find(id);
if(it != m_creators.end())
{
return std::shared_ptr<Class>((it->second)());
}
问题是,这显然不是异常保存,我试图用等效的std :: make_shared调用替换std :: shared_ptr调用。 std :: function是一个create函数,只调用Object子类的构造函数。问题是我不知道如何使用std :: function而不是std :: make shared中对构造函数的调用。这甚至可能吗?
答案 0 :(得分:2)
我会让std :: function返回一个shared_ptr而不是一个裸指针。然后你可以在std :: function中使用make_shared。
typedef std::map<uint32_t, std::function<std::shared_ptr<Class>()>> CreatorMap;
CreatorMap::iterator it = m_creators.find(id);
if(it != m_creators.end())
{
return (it->second)();
}
// example of a creator
struct SomeCreator{
public:
std::shared_ptr<Class> operator()(){
return std::make_shared<Class>();
}
}
这也允许工厂更灵活地使用自定义删除工具。
答案 1 :(得分:1)
您拥有的代码不是不安全的例外。如果在初始化期间发生异常,则带有指针的shared_ptr
构造函数将在托管指针上调用delete
。
来自N3797,§20.8.2.2.1/ 7
template<class Y> explicit shared_ptr(Y* p);
...
异常安全:如果抛出异常,则会调用delete p
。
如果它让您感觉更好,可以将map
类型更改为
std::map<uint32_t, std::function<std::unique_ptr<Class>()>>
shared_ptr
可以从unique_ptr
s构造,在这种情况下你永远不会传递原始指针。但由于我在上面引用的条款,这是不必要的。