意图:保证一个类仅有一个实例,并提供一个访问的全局访问点
--------------------singleton.h-----------------------
View Code
#ifndef SINGLETON_H
#define SINGLETON_H
class singleton
{
public:
static singleton* instance();
protected:
singleton();
private:
static singleton* _instance;
};
#endif //SINGLETON_H
---------------------singleton.cpp----------------------
View Code
#include "singleton.h"
singleton* singleton::_instance=0;
singleton* singleton::instance()
{
if (_instance==0)
{
_instance=new singleton;
}
return _instance;
}
singleton::singleton()
{
}
int main()
{
singleton *tmp=singleton::instance();
singleton *tmp2=singleton::instance();
}
1,多线程问题:
单件的通常设计成在获取对象实例的时候才创建(方便使用),但是在多线程的环境下,可能同一时刻多个线程调用获取实例方法,所以,如果保护不好很容易造成不在单件了,而是生成了很多个事例。所以单件事例在创建的时候需要加琐保护。 由于加琐会增加获取单件实例的运行负荷,所以通常我们需要对加琐进行优化。 琐的优化通常就是常听说的双检测锁的方式;
2,资源释放问题:
由于单件实例往往使用了静态数据,通常是个静态指针,而且提供一个静态的方法来获取/生成实例。这个实例通常是new出来的,使用这个实例的对象可能有很多个,于是问题来了: 这个单件实例应该如何释放呢?
能想到的可能会有下面几种方法:
1)采用引用记数,让单件的获取方,获取后自己释放;这个方法避免不了反复创建和释放单件实例,而且某一个使用者忘记释放,单件实例就再也释放不了了。
2)由一个模块负责释放单件实例,但是一旦这个模块在进程中加载多份,就又变得麻烦了,模块的销毁有先后顺序,前一个模块将单件释放了,但是后一个不知道单件已经“挂”了,如果这种场景在多线程情况下,会是什么样子,就很难说了。
参考代码:
View Code
templage <typename T>
class CAutoReleaser
{
private:
T* m_MgObject; // 受管理的对象
public:
CAutoReleaser() : m_MgObject(NULL)
{
}
virtual ~CAutoReleaser()
{
delete m_MgObject;
}
void manage(T* pObj)
{
this-> m_MgObject = pObj;
return;
}
};
class SG
{
private:
static SG* m_pInstance;
static CAutoReleaser <SG> m_autoreleaser;
SG(){}
~SG(){}
public:
static SG* getInstance()
{
if (NULL == m_pInstance)
{
SG* pnewSG = new SG;
if (pnewSG)
{
m_pInstance = pnewSG;
m_autoreleaser.manage(pnewSG);
}
}
return m_pInstance;
}
};


浙公网安备 33010602011771号