一个动态库(共享对象),它包含一个具有线程安全队列的单例类。
当你想约束一个类只被实例化一次时,使用单例。这就是而不是你想要什么:你想让你所有的插件在一个类的特定实例上工作。这里没有“只有一个人可以生活”的要求。
在C++ 11线程安全使用单迈耶的模式可能看起来像这样:
class Singleton
{
private:
Singleton();
public:
Singleton(const &Singleton) = delete;
Singleton& operator=(const &Singleton) = delete;
static Singleton& get_instance()
{
static Singleton s;
return s;
}
};
默认构造方法声明为private和复制/赋值操作都将被删除,以避免多个实例。
你需要更简单的东西:一个函数总是返回相同的实例。事情是这样的:
class Manager
{
public:
static Resource& get_resource()
{
static Resource r;
return r;
}
};
没有必要,以防止多个实例:如果你想同一个实例,只问了相同的实例。
您也可以与资源池返回给一些ID的同一实例扩展设计:
enum class ResourceId
{
ID_FOR_A_FAMILY_OF_PLUGIN,
ID_FOR_AN_OTHER_FAMILY_OF_PLUGIN
};
class Pool
{
public:
static Resource& get_resource(ResourceId id)
{
static std::map<ResourceId, Resource> p;
return p[id];
}
};
注意,在这个例子中p[id]
是与Resource
的默认构造函数动态创建。您可能需要在施工期间传递参数:
class Resource
{
public:
Resource():ready(false){}
void init(some parameters)
{
// do some intialization
ready = true;
}
bool is_ready() const { return ready; }
private:
bool ready;
};
class Pool
{
public:
static Resource& get_resource(ResourceId id)
{
static std::map<ResourceId, Resource> p;
auto& r = p[id];
if(!r.is_ready())
{
r.init(some parameters);
}
return r;
}
};
或者,使用指针,允许多态性
class Pool
{
public:
static std::unique_ptr<Resource>& get_resource(ResourceId id)
{
static std::map<ResourceId, std::unique_ptr<Resource>> p;
auto& r = p[id];
if(!r)
{
r = std::make_unique<SomeResourceTypeForId>(some parameters);
}
return r;
}
};
注意的是,过去两年实现需要周围的非静态代码互斥是thread-安全。