简述
单例模式,顾名思义,指在一个人程序中这个类只能有一个实例对象,并提供一个访问它的全局点,通常可以让全局变量可以对一个对象访问,当多次访问全局变量时,也只是得到仅有的一个对象的引用。Windows任务管理器和回收站都是非常典型的单例模式。
UML类图
类单例化
1,一个基本的类是这样的,它可以实例化无数个对象,如何对他单例化呢?
class singleton
{
public:
singleton();
};
2,上面定义的这个类,可以调用它的构造函数new出无数个类,显然违反了单列模式的定义,所以必须防止外部直接调用构造函数进行实例化.
class singleton
{
private:
singleton();
};
3,经过改进后,虽然杜绝了外部的调用构造函数直接实例化,但这个类无法使用了,它连一个对象都new不出来了,所以它要提供一个函数来让外界得到它的实例。
class singleton
{
private:
singleton();
singleton* mSingleton;
public:
singleton* GetSingleton()
{
mSingleton = new singleton;
return mSingleton;
}
}
4,再次改进后,给外界提供了一个函数可以获得它的实例,但这个函数GetSingleton还是无法调用?想要调用必须实例化,想要实例化就必须调用它,成了鸡生蛋,蛋生鸡了。怎么样才能不实例化对象就能调用这个函数呢?没错,只有用静态函数了。
class singleton
{
private:
singleton(){}
static singleton* mSingleton;
public:
static singleton* GetSingleton();
};
singleton *singleton::mSingleton = NULL;
singleton *singleton::GetSingleton()
{
mSingleton = new singleton;
return mSingleton;
}
5,再次改进后,就可以获取它的实例,但发现每次都会new一个新的对象,必须判断一下如果已经new出来就直接返回。
class singleton
{
private:
singleton(){}
static singleton* mSingleton;
public:
static singleton* GetSingleton();
};
singleton *singleton::mSingleton = NULL;
singleton *singleton::GetSingleton()
{
if (mSingleton == NULL)
{
mSingleton = new singleton;
}
return mSingleton;
}
6,一个基本的单例模式就出来了,但这个是线程不安全的,想象一下,如果量线程同时判断"mSingleton == NULL",可能都会进入执行new,就会实例化两个对象,所以再加两把互斥锁。
class singleton
{
private:
singleton(){}
static singleton* mSingleton;
public:
static singleton* GetSingleton();
};
singleton *singleton::mSingleton = NULL;
singleton *singleton::GetSingleton()
{
lock();
if (mSingleton == NULL)
{
mSingleton = new singleton;
}
unlock();
return mSingleton;
}
7,这就是一个线程安全的单例模式了。单例模式有两种方式,这是其一,叫懒汉式,只有调用GetSingleton()方法的时候才会实例化,还有一种叫饿汉式,类加载时就已经实例化好一个对象了,调用GetSingleton()时获得该对象引用饿汉式,看起来是这样的。
class singleton
{
private:
singleton(){}
static singleton* mSingleton;
public:
static singleton* GetSingleton();
};
singleton *singleton::mSingleton = new singleton;
singleton *singleton::GetSingleton()
{
return mSingleton;
}