通过std :: function调用std:make_shared

时间:2014-01-15 08:23:45

标签: c++ c++11 stl

我使用新的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中对构造函数的调用。这甚至可能吗?

2 个答案:

答案 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构造,在这种情况下你永远不会传递原始指针。但由于我在上面引用的条款,这是不必要的。