Impossible is nothing |
|
|||
愛過知情重醉過知酒濃 花開花謝終是空 緣份不停留像春風來又走 女人如花花似夢 |
公告
日歷
統計
導航常用鏈接留言簿(4)隨筆分類(4)隨筆檔案(8)文章分類(77)文章檔案(91)相冊搜索最新評論
閱讀排行榜評論排行榜 |
Singleton模式是常用的設計模式之一,但是要實現一個真正實用的設計模式卻也不是件容易的事情。 1. 標準的實現 class Singleton { public: static Singleton * Instance() { if( 0== _instance) { _instance = new Singleton; } return _instance; } protected: Singleton(void) { } virtual ~Singleton(void) { } static Singleton* _instance; }; 這是教科書上使用的方法。看起來沒有什么問題,其實包含很多的問題。下面我們一個一個的解決。 2. 自動垃圾回收 上面的程序必須記住在程序結束的時候,釋放內存。為了讓它自動的釋放內存,我們引入auto_ptr改變它。 #include <memory> #include <iostream> using namespace std; class Singleton { public: static Singleton * Instance() { if( 0== _instance.get()) { _instance.reset( new Singleton); } return _instance.get(); } protected: Singleton(void) { cout <<"Create Singleton"<<endl; } virtual ~Singleton(void) { cout << "Destroy Singleton"<<endl; } friend class auto_ptr<Singleton>; static auto_ptr<Singleton> _instance; }; //Singleton.cpp auto_ptr<Singleton> Singleton::_instance; 3. 增加模板 在我的一個工程中,有多個的Singleton類,對Singleton類,我都要實現上面這一切,這讓我覺得煩死了。于是我想到了模板來完成這些重復的工作。 現在我們要添加本文中最吸引人單件實現: /******************************************************************** (c) 2003 Module: Singleton.h Author: Yangjun D. Created: Purpose: Implement singleton pattern History: *********************************************************************/ #pragma once #include <memory> using namespace std; 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; }; template <class T> auto_ptr<T> Singleton<T>::_instance; template <class T> inline T* Singleton<T>::instance() { 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 >; } } 4. 線程安全 上面的程序可以適應單線程的程序。但是如果把它用到多線程的程序就會發生問題。主要的問題在于同時執行_instance.reset ( new T); 就會同時產生兩個新的對象,然后馬上釋放一個,這跟Singleton模式的本意不符。所以,你需要更加安全的版本: /******************************************************************** (c) 2003 Module: Singleton.h Author: Yangjun D. Created: Purpose: Implement singleton pattern History: *********************************************************************/ #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 類主要的功能是線程訪問同步,代碼如下: /****************************************************************************** Module: Interlocked.h Notices: Copyright (c) 2000 Jeffrey Richter ******************************************************************************/ #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 }; /////////////////////////////////////////////////////////////////////////////// 5. 實用方法 比如你有一個需要實現單件模式的類,就應該這樣實現: #pragma once #include "singleton.h" using namespace C2217::Pattern; class ServiceManger { public: void Run() { } private: ServiceManger(void) { } virtual ~ServiceManger(void) { } DECLARE_SINGLETON_CLASS(ServiceManger); }; typedef Singleton<ServiceManger> SSManger; 在使用的時候很簡單,跟一般的Singleton實現的方法沒有什么不同。 int _tmain(int argc, _TCHAR* argv[]) { SSManger::instance()->Run(); } 一個簡單的Singleton模式的實現,可以看到C++語言背后隱藏的豐富的語意,我希望有人能實現一個更好的Singleton讓大家學習。我從一開始實現Singleton類的過程,其實就是我學習C++的過程,越是深入越覺得C++了不起。
評論:
|
![]() |
|
Copyright © 笑笑生 | Powered by: 博客園 模板提供:滬江博客 |