//这是设计模式书中讲到的实现
class Singleton
{
public:
static Singleton* Instance(void)
{
if(NULL==instance_)
{
instance_ = new Singleton;
}
return instance_;
}
private:
Singleton(void){}
~Singleton(void){}
private:
static Singleton* instance_;
};
Singleton* Singleton::instance_ = NULL;
//但这个实现有几个问题
//1.instance_究竟什么时间销毁? 为类提供一个静态方法DestroyInstance?
//那在程序退出时究竟什么时间调用之合适呢?既要保证资源得到释放,
//又要保证在资源释放后没有其它代码引用它了。
//2.在多线程的环境下,有可能会new出两个实例
//对于上面的两个问题,解决方案如下
class Singleton
{
public:
static Singleton& Instance(void)
{
static Singleton instance;
return instance;
}
private:
Singleton(void){}
~Singleton(void){}
};
线程安全实现
//但用户如果需要控制Instance的生命期呢?但同时要保证程序在退出时正确释放
//资源,又同时保证多线程安全呢?可以按下面的方式进行实现:
class Singleton
{
private:
class CriticalSection
{
public:
CriticalSection(void)
{ InitializeCriticalSection(&cs); }
~CriticalSection(void)
{ DeleteCriticalSection(&cs); }
void Lock(void)
{ EnterCriticalSection(&cs); }
void Unlock(void)
{ LeaveCriticalSection(&cs); }
private:
CRITICAL_SECTION cs;
};
class Lock
{
public:
Lock(CriticalSection* pcs) : pcs_(pcs)
{
assert(NULL!=pcs_);
pcs_->Lock();
}
~Lock(void)
{ pcs_->Unlock(); }
private:
CriticalSection* pcs_;
}
public:
//返回引用是为了避免调用者不小心delete掉了。
static Singleton& Instance(void)
{
//这就是著名的双检测锁定,既保证了同步,又保证同步的开销最小
if(NULL==instance_.get())
{
Lock lock(&cs_);
if(NULL==instance_.get())
{
instance_.reset(new Singleton);
}
}
return *instance_.get();
}
static void DestroyInstance(void)
{
Lock lock(&cs_);
instance_.reset();
}
private:
Singleton(void){}
//不能将~Singleton声明为private,因为auto_ptr需要
private:
static auto_ptr<Singleton> instance_; //auto_ptr保证资源最后一定能得到释放
static CriticalSection cs_;
};
auto_ptr<Singleton> Singleton::instance_;
Singleton::CriticalSection Singleton::cs_;
模板实现
//为了进一步方便使用, 可以将Singleton声明为模板类
template<class T>
class SingletonT
{
private:
class CriticalSection
{
public:
CriticalSection(void)
{
InitializeCriticalSection(&cs);
}
~CriticalSection(void)
{
DeleteCriticalSection(&cs);
}
void Lock(void)
{
EnterCriticalSection(&cs);
}
void Unlock(void)
{
LeaveCriticalSection(&cs);
}
private:
CRITICAL_SECTION cs;
};
class Lock
{
public:
Lock(CriticalSection* pcs) : pcs_(pcs)
{
assert(NULL!=pcs_);
pcs_->Lock();
}
~Lock(void)
{
pcs_->Unlock();
}
private:
CriticalSection* pcs_;
}
public:
static T& Instance(void)
{
//有人说双检测锁定并不可靠,其实那是JAVA程序员的担心,C++及CRITICAL_SECTION
//在此是可以保证的, 可以放心使用的
if(NULL==instance_.get())
{
Lock lock(&cs_);
if(NULL==instance_.get())
{
instance_.reset(new T);
}
}
return *instance_.get();
}
static void DestroyInstance(void)
{
Lock lock(&cs_);
instance_.reset();
}
protected:
SingletonT(void){}
//不能将~Singleton声明为private,因为auto_ptr需要
private:
static auto_ptr<T> instance_; //auto_ptr保证资源最后一定能得到释放
static CriticalSection cs_;
};
测试
class TestClass : public SingletonT<TestClass>
{
public:
void Run()
{
}
};
int main(int argc, const char **argv)
{
argc;
argv;
TestClass::Instance().Run();
TestClass::DestroyInstance();//销毁这一个唯一的实例
TestClass::Instance().Run();//它又起死回生了
return 0;
}