上一篇實現的是使用模板 智能指針 刪除器的懶漢模式單例。
這一篇實現餓漢模式的版本。
#include <iostream>
#include <memory>
#include <windows.h>
#include <process.h>
using namespace std;
template <class T>
class CEagerSingletonPtr
{
private:
static T m_sg;
private:
CEagerSingletonPtr(const CEagerSingletonPtr&){}
CEagerSingletonPtr& operator=(const CEagerSingletonPtr&){}
protected:
CEagerSingletonPtr()
{
cout << "CEagerSingletonPtr begin construct" << endl;
::Sleep(1000);
cout << "CEagerSingletonPtr end construct" << endl;
}
protected:
virtual ~CEagerSingletonPtr()
{
cout << "CEagerSingletonPtr destrcut" << endl;
}
public:
static T& getInstance()
{
return m_sg;
}
};
// 類內靜態變量初始化
template <class T>
T CEagerSingletonPtr<T>::m_sg;
// 實例化模板
class EagerManager : public CEagerSingletonPtr<EagerManager>
{
friend class CEagerSingletonPtr<EagerManager>;
protected:
EagerManager()
{
cout << "EagerManager begin construct" << endl;
::Sleep(500);
m_count = 0;
cout << "EagerManager end construct" << endl;
}
~EagerManager()
{
cout << "EagerManager destrcut" << endl;
}
public:
void print()
{
cout << "Hello, this is EagerManage " << m_count++ << endl;
}
private:
int m_count; // 私有靜態變量
};
unsigned int __stdcall threadFun(void*)
{
cout << "Current Thread ID = " << ::GetCurrentThreadId() << endl;
EagerManager::getInstance().print();
return 0;
}
void testMultiThread()
{
for (int i = 0; i < 3; ++i)
{
uintptr_t th = ::_beginthreadex(NULL, 0, threadFun, NULL, 0, NULL);
::CloseHandle((HANDLE)th);
}
}
int main(void)
{
cout<<"歡迎進入主線程 ID = "<<::GetCurrentThreadId()<<endl;
testMultiThread();
getchar();
return 0;
}
運行結果圖:
靜態的單例是在主線程(main函數)之前就已經創建好。
當然這個版本還是有問題。 水太深~。。。
參見:Scott Meyers在其《Effective C++》第三版中的04條款的說明:
"
C++標準對於不同的編譯單元內的Non-Local-Static對象的初始化相對次序並無明確定義。
如果某一個編譯單元內的某個Non-Local-Static對象的初始化,使用了另一個編譯單元內的
某個Non-Local-Static對象,它所用到的對象可能尚未被初始化。
"