当前位置:编程学习 > 网站相关 >>

谈单例模式的线程安全(下)

在这一部分重点讲单例对象如何销毁,及单例类模板,代码中用到的CriticalSection类实现请参考第一部分。

单例对象创建方式可以分两种,一种方法是事先在静态区创建好,即创建成static的,不必考虑delete问题;另一种方法是在堆上创建,在堆上创建就要考虑销毁问题。

单例对象的销毁,可以利用静态对象生命周期来控制,静态数据在程序结束的时候自动销毁,在静态对象的析构函数中delete堆上的内存,看代码:

class SingleQueue 

public: 
  static SingleQueue* GetInstance(){ 
    if(!m_){ 
      cs.Lock();   // 注意写法,这里要同步一下 
      if(!m_){ 
        m_ = new SingleQueue; 
      } 
      cs.UnLock(); 
    } 
    return m_; 
  } 
  ~SingleQueue(){} 
 
private: 
  SingleQueue(){} 
 
private: 
  static SingleQueue* m_;           // 在cpp中初始化为NULL 
// 仅仅用于SingleQueue单例对象的回收,外界无需使用,为SingleQueue内部类且 
// private型即可。 
  class Garbo 
    { 
    public: 
      ~Garbo() 
      { 
        if(Singleton<T>::m_){ 
          delete Singleton<T>::m_; 
          Singleton<T>::m_ = NULL; 
        } 
      } 
    }; 
 
  static Garbo garbo; 
}; 

在.cpp中:

SingleQueue::Garbo SingleQueue::garbo; 

通常工程中用单例模式的类不止一个,为了使这些代码可复用,下面写了个单例类模板:


template <typename T> 
  class Singleton 
  { 
  public: 
    static T* GetInstance() 
    { 
      if(!m_) 
      { 
        garbo;              // 防止编译器将Garbo优化掉 
        cs.Lock(); 
        if(!m_) 
          m_ = new T(); 
        cs.UnLock(); 
      } 
      return m_; 
    } 
 
    ~Singleton(){} 
 
  protected: 
    Singleton(){} 
 
    static T* m_; 
    static CriticalSection cs; 
 
    class Garbo 
    { 
    public: 
      ~Garbo() 
      { 
        if(Singleton<T>::m_){ 
          delete Singleton<T>::m_; 
          Singleton<T>::m_ = NULL; 
        } 
      } 
    }; 
 
    static Garbo garbo; 
  }; 
 
  template<typename T> 
  T* Singleton<T>::m_ = NULL; 
 
  template<typename T> 
  CriticalSection Singleton<T>::cs; 
 
  template<typename T> 
  typename Singleton<T>::Garbo Singleton<T>::garbo; 

使用的时候直接从Singleton派生就可以,eg:

class CA : public Singleton< CA > 
  { 
  public: 
    friend class Singleton< CA >; // 友元是为了能调用CA的构造 
 
  protected: 
    CA (){} 
    ~ CA (){}   
  }; 

这样,CA就是一个单例类,通过CA::GetInstance ()取对象指针。

补充:综合编程 , 安全编程 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,