温故而知新,总结了多种单例模式的写法,考虑上多线程没有非常完美的,各取所需吧
//1. //Easy ,<<Pattern Design>> //Q: //When to free the m_singleton space? //when to execute the destruct function? //A:We can call getSingleton() at the end of the progress, //then delete the pointer and free the space, //but ,Here is a problem:Someone will call getSingleton() after //we delete it。How to avoid these? class Singleton { public: static Singleton* getSingleton() { if(NULL==m_singleton) { m_singleton=new Singleton(); } return m_singleton; } private: Singleton(){} ~Singleton(){} private: static Singleton* m_singleton; }; //singleton.cpp singleton* Singleton::m_singleton=NULL; //Because ,at the end of the program, all globle vars will be destructed. , //and all the static vars .we can use this point, define a static var in //the Singleton class ,it is used to delete the Singleton class .
//2.----------- class Singleton { public: staitc Singleton* getSingleton(); private: Singleton(); ~Singleton(); static Singleton* m_singleton; class Garbo//Just used for delete the static var { public: Garbo(); ~Garbo() { if(Singleton::m_singleton!=NULL) { delete Singleton::m_singleton; Singleton::m_singleton=NULL; } } } staitc Garbo m_garbo;//define a static var, } //singleton.cpp Garbo Singleton::m_garbo; //
//3.--------------- class Singleton { public: staitc Singleton* getSingletonPtr() { if(NULL==m_singleton) { m_singleton.reset(new Singleton); } return m_singleton.get(); } protected: Singleton(){} virtual ~Singleton(){} friend class auto_ptr<Singleton>; static auto_ptr<Singleton> m_singleton; };
//singleton.cpp auto_ptr<Singleton> Singleton::m_singleton=NULL;
//4. class Singleton { public: static Singleton* getSingletonPtr() { staitc Singleton singleton; return &singleton; } private: Singleton(){} ~Singleton(){} }
//5. class Singleton { public: staitc Singleton& getSingleton { return m_singleton; } private: staitc Singleton m_singleton; Singleton(){} }
//6.---------thread safe
#pragma once #include <memory> using namespace std; #include "Interlocked.h" using namespace C2217::Win32; namespace C2217 { namespace Pattern { template <class T> class Singleton { public: static inline T* instance(); private: Singleton(void){} ~Singleton(void){} Singleton(const Singleton&){} Singleton & operator= (const Singleton &){} static auto_ptr<T> _instance; static CResGuard _rs; }; template <class T> auto_ptr<T> Singleton<T>::_instance; template <class T> CResGuard Singleton<T>::_rs; template <class T> inline T* Singleton<T>::instance() { if( 0 == _instance.get() ) { CResGuard::CGuard gd(_rs); if( 0== _instance.get()) { _instance.reset ( new T); } } return _instance.get(); } //Class that will implement the singleton mode, //must use the macro in it's delare file #define DECLARE_SINGLETON_CLASS( type ) \ friend class auto_ptr< type >;\ friend class Singleton< type >; } } // CresGuard 类主要的功能是线程访问同步,代码如下: /**//******************************************************************************
******************************************************************************/ #pragma once /**//////////////////////////////////////////////////////////////////////////////// // Instances of this class will be accessed by multiple threads. So, // all members of this class (except the constructor and destructor) // must be thread-safe. class CResGuard { public: CResGuard() { m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); } ~CResGuard() { DeleteCriticalSection(&m_cs); } // IsGuarded is used for debugging BOOL IsGuarded() const { return(m_lGrdCnt > 0); } public: class CGuard { public: CGuard(CResGuard& rg) : m_rg(rg) { m_rg.Guard(); }; ~CGuard() { m_rg.Unguard(); } private: CResGuard& m_rg; }; private: void Guard() { EnterCriticalSection(&m_cs); m_lGrdCnt++; } void Unguard() { m_lGrdCnt--; LeaveCriticalSection(&m_cs); } // Guard/Unguard can only be accessed by the nested CGuard class. friend class CResGuard::CGuard; private: CRITICAL_SECTION m_cs; long m_lGrdCnt; // # of EnterCriticalSection calls };
//7. most used template <typename T> class Singleton { public : static T& getSingleton() { return *m_singlon; }
static T* getSingletonPtr() { return m_singlon; } protected:
Singleton() { m_singlon=static_cast<T*>(this); }
~Singleton() { m_singlon=NULL; } private: Singleton(const Singleton&){}
Singleton& operator=(const Singleton&){}
static T* m_singlon; };
template<typename T> T* Singleton<T>::m_singlon = NULL;
|