From the name we can see that a singleton class is a kind of class that only has one class object. Why we need to use this pattern? Sometimes we can use it instead of the global variables.
Here is an implementation of singleton class:
template <typename TData> class CThreadData { // construction / destruction private: CThreadData(CThreadData const&); // prevent copy construction TData *m_pTData;
protected: CThreadData() // disallow illegal construction {}
public: virtual ~CThreadData() // this should be private: VC++ bug! {}
// singleton operations, get the reference of the only class object public: static CThreadData<TData>& Instance(void);
// operations public: void AllocData(void) { // only once _ASSERTE(GetValue() == 0); SetValue(new TData()); }
void FreeData(void) { TData* pData = GetValue(); if (pData != 0) { delete pData; SetValue(0); } }
void SetValue(TData* pvData) { m_pTData = pvData;}
TData *const GetValue(void) const { return m_pTData;}
TData *GetValue(void) { return m_pTData;}
// data members protected: static CThreadData *m_pInstance; };
template <typename TData> CThreadData<TData>* CThreadData<TData>::m_pInstance = 0;
template <typename TData> CThreadData<TData>& CThreadData<TData>::Instance(void) { if (m_pInstance == 0) { static CThreadData<TData> instance; m_pInstance = &instance; }
return (*m_pInstance); } |
Here is the test code
template <typename TData> class ThreadData { public: ThreadData() {m_dwData = 1;};
TData GetValue() {return m_dwData;}; void SetValue(TData pData) {m_dwData = pData;}; private: TData m_dwData; };
typedef ThreadData<DWORD> ThreadDataDWORD;
int _tmain(int argc, _TCHAR* argv[]) { CThreadData<ThreadDataDWORD> &rOnlyOne = CThreadData<ThreadDataDWORD>::Instance();
rOnlyOne.AllocData();
ThreadData<DWORD> *pTD = rOnlyOne.GetValue(); printf ("data: %d/n", pTD->GetValue()); pTD->SetValue(8); printf ("data: %d/n", pTD->GetValue());
rOnlyOne.FreeData(); } |
We may use this structure to manage the TLS functions.
More details: http://www.codeproject.com/KB/threads/threaddata.aspx