#ifndef __CSINGLETON_H__ #define __CSINGLETON_H__ template <typename T> class CSingleton { protected: CSingleton(); ~CSingleton(); public: static T * GetInstance(){if(m_pObject==NULL){m_pObject=new T;} return m_pObject; } static void ReleaseInstance(){if(m_pObject!=NULL){delete m_pObject;m_pObject=NULL; }} private: static T * m_pObject; }; template <typename T> T* CSingleton<T>::m_pObject=NULL; //////////////////////////////////////////////////////////// class CCriticalSection { public: CCriticalSection(){InitializeCriticalSection(&m_cs);} ~CCriticalSection(){DeleteCriticalSection(&m_cs);} public: void Lock(){EnterCriticalSection(&m_cs);} void UnLock(){LeaveCriticalSection(&m_cs);} private: CRITICAL_SECTION m_cs; }; #define synchronized(X,CS) CS.Lock();{ X } CS.UnLock() template< class T > class CSafePtr { public: CSafePtr(T* p) : m_p(p) { } ~CSafePtr() { if( m_p != NULL ) m_p->Release(); } public: T* Detach() { T* t = m_p; m_p = NULL; return t; } T* Attach(T* p){T* t = m_p; m_p = p; return t;} T* operator -> (){ if( m_p != NULL){ return m_p;} else {ASSERT(m_p!=NULL);}} protected: T* m_p; }; #endif
單態模式總結: 一、通常實現方式安全
class Singleton { public: static Singleton *GetInstance() { if (m_Instance == NULL ) { m_Instance = new Singleton (); } return m_Instance; } static void DestoryInstance() { if (m_Instance != NULL ) { delete m_Instance; m_Instance = NULL ; } } private: Singleton(){} static Singleton *m_Instance; }; Singleton *Singleton ::m_Instance = NULL;
二、考慮到多線程的問題,在多線程的狀況下實現 (兩次m_Instance == NULL的判斷,是借鑑了Java的單例模式實現時,使用的所謂的「雙檢鎖」機制。由於進行一次加鎖和解鎖是須要付出對應的代價的,而進行兩次判斷,就能夠避免屢次加鎖與解鎖操做,同時也保證了線程安全。)多線程
class Singleton { public: static Singleton *GetInstance() { if (m_Instance == NULL ) { Lock(); // C++沒有直接的Lock操做,請使用其它庫的Lock,好比Boost,此處僅爲了說明 if (m_Instance == NULL ) { m_Instance = new Singleton (); } UnLock(); // C++沒有直接的Lock操做,請使用其它庫的Lock,好比Boost,此處僅爲了說明 } return m_Instance; } static void DestoryInstance() { if (m_Instance != NULL ) { delete m_Instance; m_Instance = NULL ; } } private: Singleton(){ } static Singleton *m_Instance; }; Singleton *Singleton ::m_Instance = NULL;
三、若是進行大數據的操做,加鎖操做將成爲一個性能的瓶頸;可使用下面一種實現 (進入主函數以前,由主線程以單線程方式完成了初始化,因此靜態初始化實例保證了線程安全性。在性能要求比較高時,就可使用這種方式。)函數
class Singleton { public: static Singleton *GetInstance() { return const_cast <Singleton *>(m_Instance); } static void DestoryInstance() { if (m_Instance != NULL ) { delete m_Instance; m_Instance = NULL ; } } private: Singleton(){} static const Singleton *m_Instance; }; const Singleton *Singleton ::m_Instance = new Singleton();
四、不須要調用釋放函數性能
class Singleton { public: static Singleton *GetInstance() { static Singleton m_Instance; return &m_Instance; } private: Singleton(){}; };
五、定義內部類,自動回收大數據
class Singleton { public: static Singleton *GetInstance() { return m_Instance; } private: Singleton(){} static Singleton *m_Instance; // This is important class GC { public : ~GC() { // We can destory all the resouce here, eg:db connector, file handle and so on if (m_Instance != NULL ) { cout<< "Here is the test" <<endl; delete m_Instance; m_Instance = NULL ; } } }; static GC gc; }; Singleton *Singleton ::m_Instance = new Singleton(); Singleton ::GC Singleton ::gc;