常見的單例模式使用 static 局部變量(Meyers Singleton),但 C++11 前編譯器不保證其線程安全。即使 C++11 標準化了魔法靜態的線程安全初始化,某些舊編譯器/嵌入式平台可能不支持。本文實現一個顯式線程安全的單例工廠。
Tstd::auto_ptr 管理單例對象生命週期(C++11 前智能指針),析構時自動釋放CreateSingletonFactory 返回靜態實例)
#ifndef SINGLETONFACTORY_H
#define SINGLETONFACTORY_H
#include <windows.h>
#include <memory>
namespace Tools {
template<class T>
class SingletonFactory {
public:
virtual ~SingletonFactory() {
::DeleteCriticalSection(&__criticalSection);
}
std::auto_ptr<T>& GetInstance();
static SingletonFactory<T>* CreateSingletonFactory();
private:
SingletonFactory() {
::InitializeCriticalSection(&__criticalSection);
}
std::auto_ptr<T> __singletonObj;
CRITICAL_SECTION __criticalSection;
};
// 工廠單例創建(靜態局部變量,C++11 保證線程安全)
template<class T>
SingletonFactory<T>* SingletonFactory<T>::CreateSingletonFactory() {
static SingletonFactory<T> temObj;
return &temObj;
}
// 雙重檢查鎖定獲取單例實例
template<class T>
std::auto_ptr<T>& SingletonFactory<T>::GetInstance() {
if (__singletonObj.get() == 0) {
::EnterCriticalSection(&__criticalSection);
if (__singletonObj.get() == 0)
__singletonObj = std::auto_ptr<T>(new T);
::LeaveCriticalSection(&__criticalSection);
}
return __singletonObj;
}
} // namespace Tools
#endif // SINGLETONFACTORY_H
struct Data1 { int x, y; };
struct Data2 { int x, y; };
int main() {
// 獲取工廠單例,再獲取數據單例
SingletonFactory<Data1>* factory1 = SingletonFactory<Data1>::CreateSingletonFactory();
factory1->GetInstance()->x = 100;
cout << factory1->GetInstance()->x << endl; // 100
factory1->GetInstance()->y = 200;
cout << factory1->GetInstance()->x << endl; // 100
cout << factory1->GetInstance()->y << endl; // 200
SingletonFactory<Data2>* factory2 = SingletonFactory<Data2>::CreateSingletonFactory();
factory2->GetInstance()->x = 100;
cout << factory2->GetInstance()->x << endl;
factory2->GetInstance()->y = 200;
cout << factory2->GetInstance()->x << endl;
cout << factory2->GetInstance()->y << endl;
return 0;
}
static T instance 魔法靜態,標準保證線程安全,代碼極簡std::auto_ptr 為 std::unique_ptr(C++11)或 std::shared_ptrstd::mutex + std::call_once 替代 Critical Sectionstd::atomic<T*> + 雙重檢查 + memory_order_acquire/release