简介
单例模式是软件开发过程中经常用到的一种设计模式,它可以一个类只有一个实例,并且提供一个访问它的全局访问点,这个实例被所有程序模块共享。
C++实现
设计模式里面给出了一种很不错的实现,首先定义一个单例类,该类中含有一个指向该类元素静态私有指针变量,同时含有一个静态函数,函数在该类尚无实例的时候通过new操作符产生一个类的实例,若类的实例已经产生过了,直接返回已存在的实例的指针。
代码:
class CSingleton
{
public:
static CSingleton* getInstance()
{
if (mInstance == NULL)
mInstance = new CSingleton();
return mInstance;
}
private:
CSingleton(){}
static CSingleton* mInstance;
};
CSingleton* CSingleton::mInstance = NULL;
单例模式的删除操作
单例模式中产生的实例位于动态存储区,必须通过手动调用delete进行删除,我们可以在程序结束的时候调用getInstance,然后delete掉返回的指针,这样做虽然可实现删除操作,但是程序很容易出错。一个更好的做法是让类自己完成delete操作。我们的做法是定义一个删除类,在类的析构函数中调用delete 操作删除CSingleton的实例。
为了让这个类的析构函数在程序结束的时候执行,我们将这个删除类作为CSingleton的静态成员:
代码:
class CSingleton
{
public:
static CSingleton* getInstance()
{
if (mInstance == NULL)
mInstance = new CSingleton();
return mInstance;
}
private:
CSingleton(){}
static CSingleton* mInstance;
private:
class Deleter
{
public:
~Deleter()
{
delete CSingleton::mInstance;
}
};
private:
static Deleter deleter;
};
CSingleton* CSingleton::mInstance = NULL;
单例模式的线程安全
在多线程环境下使用单例模式,考虑这样一种情况,类的实例还未被创建,线程一调用getInstance函数,执行if(mInstance==NULL)这一步,if条件满足,此时线程一时间片恰好用完,线程二被调度执行,若线程二恰好也执行getInstance操作,并成功创建一个实例,线程一恢复调度时,恢复到上一次执行的代码处,再次创建了一个实例。可见,在多线程环境下,上面的单例模式存在出错的可能,必须设计同步机制,避免这种情况出现。
懒汉模式
懒汉模式指的是在需要该类实例的时候才产生一个新的实例,这种情况下需要用加锁来保证其线程安全性。
加锁的单例模式代码:
class CSingleton
{
public:
static CSingleton* getInstance()
{
Lock();
if (mInstance == NULL)
mInstance = new CSingleton();
unLock();
return mInstance;
}
private:
CSingleton(){}
static CSingleton* mInstance;
private:
class Deleter
{
public:
~Deleter()
{
delete CSingleton::mInstance;
}
};
private:
static Deleter deleter;
};
CSingleton* CSingleton::mInstance = NULL;
饿汉模式
饿汉模式指的是静态实例初始化在进入主函数之前就由主线程以单线程的形式完成了初始化,避免了多线程下重复创建实例的可能性。
C++代码:
class SingletonStatic
{
private:
static const SingletonStatic* mInstance;
SingletonStatic(){};
public:
static const SingletonStatic* getInstance()
{
return mInstance;
}
};
const SingletonStatic* SingletonStatic::mInstance = new SingletonStatic();