前言
单例模式的实现方法很多,但是其中的门门道道很值得研究。
单例模式的意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。这让我们想到类的静态函数只能由类来调用,这个方法就跟类的实例没有关系了。这个方法的作用是获取类的私有静态类的指针。这个类的指针在类被声明的时候就被初始化,并且是静态的,跟实例无关,因此,每次调用静态成员方法的时候,都会获取同一个指针。
实现一:
class CSingleton
{
public:
static CSingleton * GetInstance()
{
if(m_pInstance == NULL) //判断是否第一次调用
m_pInstance = new CSingleton();
return m_pInstance;
}
private:
CSingleton() //构造函数是私有的
{
}
static CSingleton *m_pInstance; //静态类的指针,在声明时被初始化
};
这样就可以了,保证只取得了一个实例。但是在多线程的环境下却不行了,因为很可能两个线程同时运行到if (instance == NULL)这一句,导致可能会产生两个实例。于是就要在代码中加锁。
实现二:
class CSingleton
{
public:
static CSingleton * GetInstance()
{
lock();
if(m_pInstance == NULL) //判断是否第一次调用
{
m_pInstance = new CSingleton();
}
unlock();
return m_pInstance;
}
private:
CSingleton() //构造函数是私有的
{
}
static CSingleton *m_pInstance; //静态类的指针,在声明时被初始化
};
但这样写的话,会稍稍影响性能,因为每次判断是否为空都需要被锁定,如果有很多线程的话,就会造成大量线程的阻塞。于是有了改进:
class CSingleton
{
public:
static CSingleton * GetInstance()
{
if(m_pInstance == NULL) //先判断一次
{
lock();
if(m_pInstance == NULL) //判断是否第一次调用
{
m_pInstance = new CSingleton();
}
unlock();
}
return m_pInstance;
}
private:
CSingleton() {} //构造函数是私有的
static CSingleton *m_pInstance; //静态类的指针,在声明时被初始化
};