我要求在任何给定的时间点只有一个类的单个实例。单身人士是明显的候选人。 但我还有其他一些不典型的单身人士条件。
所以我的实现有以下静态函数 -
// To be called exactly once, everytime I enter the state
void MySingleton::CreateInstance(size_t count);
// To be called any no. of times during the state
MySingleton * MySingleton::GetInstance();
// To be called exactly once, when leaving the state.
void MySingleton::DestroyInstance();
现在,这种实现是传统单例实现的主要迂回。
这种实施有问题吗?
还有更好的选择吗?
答案 0 :(得分:12)
如果每次进入给定状态时都创建一个实例,并在每次离开该状态时将其销毁,那么让实例归属于管理状态转换(或其他一些知道的实体)所有者更有意义国家转型)。
例如,您可以将一个指向实例的智能指针作为状态管理器的成员变量。当您转换到状态时,您可以将其初始化为新实例,当您转出状态时,您可以销毁该实例。
在我看来,这比使用单身设计(反)模式更清洁,更可取。
答案 1 :(得分:5)
这种实施有问题吗?
是的。问题是这不是Singleton ,因为它不是“Singleton”模式的全部内容。这是一个简单的变量,是你进入和离开的那个州的本地变量。
实际上,单身人士只是美化全球化,在整个应用程序的整个生命周期中都存活,无论如何都应该尽可能地防止。你的“单身人士”不是全球性的,而是一个地方性的。
答案 2 :(得分:2)
您所描述的概念可以通过以下类来确保:
template<class Guarded>
class single_instance : private boost::noncopyable {
static bool alive;
public:
single_instance() {
if (alive)
throw std::runtime_error("instance already exists");
alive = true;
}
~single_instance() {
alive = false;
}
};
template<class Guarded>
bool single_instance<Guarded>::alive = false;
如果您从中派生您的类,将确保您始终只能一次创建一个实例:
class myclass : single_instance<myclass> {
public:
myclass(size_t count);
...
};
现在,您可以像普通类一样实现myclass
,而无需工厂函数和getInstance
方法。尝试在销毁第一个副本之前实例化第二个副本将引发异常。
答案 3 :(得分:1)
如果它是每个状态一个,那么从你的状态对象中创建它,并使构造函数为private,friend state。
答案 4 :(得分:1)
我完全同意“辛格尔顿只是另一种形式的全球化”,应该避免使用。
如果你的老板坚持,你可以尝试这样的事情:
class MyUtil
{
protected:
static MyUtil* m_Singleton = NULL;
public:
/// Create the singleton if does not exist.
/// \return the singleton for this class.
static GetSingleton()
{
if( !m_Singleton )
m_Singleton = new MyUtil();
return m_Singleton ;
}
/// release singleton instance
/// Warning: Multi-threading not supported.
void StateRelease()
{
m_Singleton = NULL;
delete this;
}
};
答案 5 :(得分:0)
我认为这种解决方案的性能时间很长。我只创建一个实例,并将创建函数更改为:
void MySingleton::reset(size_t count);