使用l临界区来实现单例模式
#include <stdlib.h>
#include <Windows.h>
class Mutex {
public:
Mutex() { InitializeCriticalSection(§ion); }
~Mutex() { DeleteCriticalSection(§ion); }
void Enter() { EnterCriticalSection(§ion); }
void Leave() { LeaveCriticalSection(§ion); }
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;
}
#include <Windows.h>
class Mutex {
public:
Mutex() { InitializeCriticalSection(§ion); }
~Mutex() { DeleteCriticalSection(§ion); }
void Enter() { EnterCriticalSection(§ion); }
void Leave() { LeaveCriticalSection(§ion); }
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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.