使用l临界区来实现单例模式

#include <stdlib.h>
#include <Windows.h>




class Mutex {  
public:  
Mutex()                      { InitializeCriticalSection(&section); }  
~Mutex()                     { DeleteCriticalSection(&section); }  
void  Enter()                { EnterCriticalSection(&section); }  
void  Leave()                { LeaveCriticalSection(&section); }  


struct Lock; 
Mutex(const Mutex&);  
Mutex& operator=(const Mutex&);  


protected:  




CRITICAL_SECTION section;  
};  


struct Mutex::Lock {  
Mutex& s;  
Lock(Mutex& s):s(s) { s.Enter(); }  
~Lock()               { s.Leave(); }  
};  


template<typename T, typename LOCK>
class HySingleton
{
public:
static T* Instance()
{
if (!m_pInstance)
{
MakeInstance();
}
return m_pInstance;
}


private:
/************************************************************************
Singleton这个类本身是一个永远不会被实例化的类,所以没有构造和析构调用
这里确保“析构函数”被调用,其实现手法和编译器处理析构函数很类似
确保程序退出的时候T的析构函数被调用,并且执行相关清理动作
************************************************************************/
static void MakeInstance()
{
//在这里加入多线程保护,TODO
//这里采用"双检测锁定",在调用MakeInstance之前已经检查过一次了
//LOCK::HyAutoLock _lock(m_lock);
Mutex::Lock _lock(m_lock);


if (!m_pInstance)
{
if(m_bDestroyed)
{
//Dead Reference Detected
OnDeadReference();


//OnDeadReference()没有抛出异产的话
//对象就会"复活"
m_bDestroyed = false;
}


m_pInstance = new T;


//每次new完后,要确保delete
atexit(DestroySingleton);
}
}




/************************************************************************
如果在程序结束时,单体内的静态成员已经析构。
有另一个寿命更长的对象访问这个单体,就会出现引用失效。
因为谁也不知道编译按什么顺序销毁对象(好像是先生成的后销毁,即atexit以stack方式运作,见MSDN和C++方案)。
************************************************************************/


/************************************************************************
让对象销毁
************************************************************************/
static void DestroySingleton()
{
if(m_bDestroyed)
{
throw ("Singleton has been destroyed!");
}


//销毁T的实例
delete m_pInstance;


//设置状态
m_pInstance = NULL;


m_bDestroyed = true;
}


/************************************************************************
当检测到调用已经销毁的对象时,调用该函数
************************************************************************/
static void OnDeadReference()
{
//这里什么都不做可以让已经被销毁的静态成员变量复活
//但是对于状态复杂的对象,单实例化是不足以使对象工作的
//而且这里好像没有办法插入T所需要的初始化代码,因为这个时候程序正在结束中
//所以也可以抛出异常结束程序
// throw std::runtime_error("Dead Reference Detected");


}


static T* m_pInstance;


static bool m_bDestroyed;


 
    static LOCK m_lock;


};
template<typename T, typename LOCK> T* HySingleton<T, LOCK>::m_pInstance = NULL;


template<typename T, typename LOCK> bool HySingleton<T, LOCK>::m_bDestroyed = false;


template<typename T, typename LOCK> LOCK HySingleton<T, LOCK>::m_lock;




#define USE_SINGLETON template<typename T,typename LOCK> friend class HySingleton;


class MyClass
//: public HySingleton<MyClass,Mutex>
{
 
public:
//friend class HySingleton<MyClass,Mutex>;
USE_SINGLETON
MyClass(){};
~MyClass(){};
void Print() { printf("testing %d\n",val); }
int val;
};   
 #define GetDeviceDefinePtr() HySingleton<MyClass,Mutex>::Instance()
 
int _tmain(int argc, _TCHAR* argv[])
{
 
HySingleton<MyClass,Mutex>::Instance()->val=9;
GetDeviceDefinePtr()->Print();

return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章