Singleton 模式的问题探究及多线程下设计问题

Singleton模式的经典实现如下:

 

class Singleton

{

public:

       static Singleton * GetInstance()

       {

              if( 0== m_instance)

              {

                     m_instance = new Singleton;

              }

              return m_instance;

       }

protected:

       Singleton(void)

       {

       }

       virtual ~Singleton(void)

       {

       }

       static Singleton* m_instance;

};

 

实现虽然简单,但是潜在问题很多。

首先,为避免内存泄露,要注意回收资源,为了打到自动回收,可以用auto_ptr解决。

 

using namespace std;

class Singleton

{

public:

       static Singleton * GetInstance()

       {

              if( 0== m_instance.get())

              {

                     m_instance.reset( new Singleton);

              }

              return m_instance.get();

       }

protected:

       Singleton(void)

       {

       }

       virtual ~Singleton(void)

       {

       }

       friend class auto_ptr<Singleton>;

       static auto_ptr<Singleton> m_instance;

};

 

//Singleton.cpp

auto_ptr<Singleton> Singleton::_instance;

 

 

其次也是很重要的就是多线程下的注意问题,《深入浅出设计模式》里面提到,当然是在Java的使用环境下,有三种解决方法,在第五章有解释。

 

这里,我们用C++再次诠释,当然还是最常用的double-check方法来保证单件模式的线程安全,代码用模板来做。

 

template <class T>

class Singleton

{

public:

       static inline T* GetInstance();

      

private:

       Singleton(void)

       {

       }

       ~Singleton(void)

       {

       }

       Singleton(const Singleton&)

       {

       }

       Singleton & operator= (const Singleton &)

       {

       }

 

       static auto_ptr<T> m_instance;

       static CLock m_lock;

};

 

template <class T>

auto_ptr<T> Singleton<T>::m_instance;

 

template <class T>

CLock Singleton<T>::m_lock;

 

template <class T>

 inline T* Singleton<T>::GetInstance()

{

       if( 0 == m_instance.get() )

       {

              CLock::Lock lock(m_lock);

              if( 0== m_instance.get())

              {

                     m_instance.reset ( new T);

              }

       }

       return m_instance.get();

}

 

下面是CLock 的实现:

// 所有的成员函数都必须是线程安全的。

class CLock

{

public:

   CLock()  { m_lockCnt = 0; InitializeCriticalSection(&m_cs); }

   ~CLock() { DeleteCriticalSection(&m_cs); }

 

   // IsGuarded is used for debugging

   BOOL IsLocked() const { return(m_lGrdCnt > 0); }

 

public:

   class Lock

  {

   public:

      Lock(CLock & rg) : m_rg(rg) { m_rg.Locked(); };

      ~Lock() { m_rg.UnLocked(); }

 

   private:

      CLock & m_rg;

   };

 

private:

   void Locked()  

   {

       EnterCriticalSection(&m_cs);

       m_lockCnt++;

    }

   void UnLocked()

   {

        m_lockCnt--;

        LeaveCriticalSection(&m_cs);

    }

 

   friend class CLock::Lock;

 

private:

   CRITICAL_SECTION m_cs;

   long m_lockCnt;   // # of EnterCriticalSection calls

};

 

 

Reference : http://www.cppblog.com/dyj057/archive/2009/04/17/346.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值