Singleton的各种实现

  标准实现

//是设计模式书中讲到的实现
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值