Design Patterns
Материал из Wiki.crossplatform.ru
(Различия между версиями)
ViGOur (Обсуждение | вклад) (→Одиночка (Singleton)) |
ViGOur (Обсуждение | вклад) (→Одиночка (Singleton)) |
||
Строка 142: | Строка 142: | ||
return 0; | return 0; | ||
+ | }</source> | ||
+ | |||
+ | === Многопоточный (double-checked locking) === | ||
+ | <source lang="cpp">#include <cstdlib> | ||
+ | #include <boost/thread/once.hpp> | ||
+ | |||
+ | template <class T> | ||
+ | class Singleton | ||
+ | { | ||
+ | public: | ||
+ | static T& Instance(); | ||
+ | |||
+ | private: | ||
+ | Singleton() {}; | ||
+ | Singleton(const Singleton&); | ||
+ | Singleton& operator=(const Singleton&); | ||
+ | virtual ~Singleton() {}; | ||
+ | |||
+ | static void Init() { boost::call_once(m_init, &Singleton<T>::InitImpl); } | ||
+ | static void InitImpl() { m_me = new T; atexit(&Singleton<T>::FreeInstance); } | ||
+ | static void FreeInstance() { boost::call_once(m_done, &Singleton<T>::FreeImpl); }; | ||
+ | static void FreeImpl() { delete m_me; m_me = NULL; } | ||
+ | friend int atexit(void (__cdecl *func)(void)); | ||
+ | |||
+ | private: | ||
+ | static T* volatile m_me; | ||
+ | static boost::once_flag m_init, m_done; | ||
+ | }; | ||
+ | |||
+ | template <class T> | ||
+ | T* Singleton<T>::m_me = NULL; | ||
+ | |||
+ | template <class T> | ||
+ | boost::once_flag Singleton<T>::m_init = BOOST_ONCE_INIT; | ||
+ | |||
+ | template <class T> | ||
+ | boost::once_flag Singleton<T>::m_done = BOOST_ONCE_INIT; | ||
+ | |||
+ | template <class T> | ||
+ | T& Singleton<T>::Instance() | ||
+ | { | ||
+ | Init(); | ||
+ | return (*m_me); | ||
}</source> | }</source> | ||
Версия 07:29, 16 апреля 2013
Порождающие паттерны проектирования
Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit)
Одиночка (Singleton)
Статический
class CSingleton { private: static CSingleton m_singleton; private: CSingleton() {} ~CSingleton() {} CSingleton(const CSingleton &) {} CSingleton & operator=(const CSingleton &) { return *this; } public: static CSingleton *instance() { return &m_singleton; } }; CSingleton CSingleton::m_singleton; int main(int , char **) { CSingleton *p = CSingleton::instance(); // ... return 0; }
Динамический
class CSingleton { private: static CSingleton *m_pSingleton; static int m_nCounter; private: CSingleton() {} ~CSingleton() {} CSingleton(const CSingleton &) {} CSingleton & operator=(const CSingleton &) { return *this; } public: static CSingleton *instance() { if( m_nCounter == 0 ) { m_pSingleton = new CSingleton(); } m_nCounter++; return m_pSingleton; } static CSingleton *freeInstance() { if( m_nCounter > 0 ) { m_nCounter--; if( m_nCounter == 0 ) { delete m_pSingleton; m_pSingleton = 0; } } } }; CSingleton *CSingleton::m_pSingleton = 0; int CSingleton::m_nCounter = 0; int main(int , char **) { CSingleton *p = CSingleton::instance(); return 0; }
Шаблонный
class CClass { public: virtual ~CClass(){ } }; template <class T> class CTypedSingleton; template<class T> class CTypedWrapper : public T, private CTypedSingleton<T> { public: void operator delete(void *p) { CTypedSingleton<T>::free(); } }; template <class T> class CTypedSingleton { static T* m_self; static int m_refcount; protected: CTypedSingleton(){} CTypedSingleton(const CTypedSingleton&){} virtual ~CTypedSingleton(){ m_self = 0; } CTypedSingleton &operator=(const CTypedSingleton&){} public: static T *init() { if(!m_self) m_self = new CTypedWrapper<T>; m_refcount++; return m_self; } static void free() { if( m_refcount > 0) { --m_refcount; if( m_refcount == 0) { delete m_self; m_self = 0; } } } }; template <class T> T *CTypedSingleton<T>::m_self = 0; template <class T> int CTypedSingleton<T>::m_refcount = 0; int main(int , char **) { CClass *p = CTypedSingleton<CClass>::init(); delete p; return 0; }
Многопоточный (double-checked locking)
#include <cstdlib> #include <boost/thread/once.hpp> template <class T> class Singleton { public: static T& Instance(); private: Singleton() {}; Singleton(const Singleton&); Singleton& operator=(const Singleton&); virtual ~Singleton() {}; static void Init() { boost::call_once(m_init, &Singleton<T>::InitImpl); } static void InitImpl() { m_me = new T; atexit(&Singleton<T>::FreeInstance); } static void FreeInstance() { boost::call_once(m_done, &Singleton<T>::FreeImpl); }; static void FreeImpl() { delete m_me; m_me = NULL; } friend int atexit(void (__cdecl *func)(void)); private: static T* volatile m_me; static boost::once_flag m_init, m_done; }; template <class T> T* Singleton<T>::m_me = NULL; template <class T> boost::once_flag Singleton<T>::m_init = BOOST_ONCE_INIT; template <class T> boost::once_flag Singleton<T>::m_done = BOOST_ONCE_INIT; template <class T> T& Singleton<T>::Instance() { Init(); return (*m_me); }