我們見到經常有人用 static 局部對象的方式實現了類似單例模式,最近發現一篇文章明確寫明 編譯器在處理 static局部變量的時候 並不是線程安全的 !!!
於是實現了一個單例工廠 並且是線程安全的
#ifndef SINGLETONFACTORY_H #define SINGLETONFACTORY_H #include windows.h #includenamespace Tools { template class SingletonFactory { public: virtual ~SingletonFactory() { ::DeleteCriticalSection(&__criticalSection); } std::auto_ptr & GetInstance(); static SingletonFactory * CreateSingletonFactory(); private: SingletonFactory() { ::InitializeCriticalSection(&__criticalSection); } std::auto_ptr __singletonObj; CRITICAL_SECTION __criticalSection; }; //初始化創建 後續在多線程中使用 //還有另一種寫法是單獨的函數直接返回內部單例包裝靜態成員在 多線程情況下不安全 //SingletonFactory::CreateSingletonFactory().GetInstance(); template SingletonFactory * SingletonFactory ::CreateSingletonFactory(){ static SingletonFactory temObj; return &temObj; } //工廠實例 template std::auto_ptr & SingletonFactory ::GetInstance() { if(__singletonObj.get()==0) { ::EnterCriticalSection(&__criticalSection); if(__singletonObj.get()==0) __singletonObj=std::auto_ptr (new T); ::LeaveCriticalSection(&__criticalSection); } return __singletonObj; } } #endif // SINGLETONFACTORY_H
測試代碼
SingletonFactory*singleton1=SingletonFactory ::CreateSingletonFactory(); singleton1->GetInstance()->x=100; cout< GetInstance()->x< GetInstance()->y=200; cout< GetInstance()->x< GetInstance()->y< *singleton2=SingletonFactory ::CreateSingletonFactory(); singleton2->GetInstance()->x=100; cout< GetInstance()->x< GetInstance()->y=200; cout< GetInstance()->x< GetInstance()->y<