单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但是它不能防止实例化多个对象。一个最好的方法就是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。因此,单例模式主要来解决一个全局使用的类频繁地创建和销毁地问题。单例模式下可以确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
优点:(1)在内存里只有一个实例,减少了内存的开销,尤其是频繁地创建和销毁实例;(2)避免对资源的多重占用。
缺点:没有接口,不能继承,与单一职责原则相冲突,一个类应该只关心其内部逻辑,而不用关心外面怎么样来实例化。
单例模式下,如果不采取任何措施的话,在多线程下是不安全的,可能会同时创建多个实例。因此,为了保证单例模式在多线程下的线程安全,一般采用以下几种方式来实现单例模式:
(1)饿汉式单例:基于类继承机制避免多线程的同步问题,但是,实例在类装载时就实例化可能会产生垃圾对象。
class Singleton
{
private:
//构造函数为私有的,保证其他类对象不能直接new一个该对象的实例
Singleton()
{}
//直接初始化一个实例对象
static Singleton instance = new Singleton();
public:
//该类的唯一的一个公有函数
static Singleton getInstance()
{
return instance;
}
}
(2)懒汉式单例:通过双重锁机制实现线程安全。
class Singleton
{
private:
//直接初始化一个实例对象
Singleton instance;
//构造函数为私有的,保证其他类对象不能直接new一个该对象的实例
Singleton()
{}
public:
//该类的唯一的一个公有函数,对获取实例的方法进行同步
Singleton getInstance()
{
if(instance == NULL)
{
synchronized(Singleton.class)
{
if(instance == NULL)
{
instance = new Singleton();
}
}
}
return instance;
}
}
单例模式要求类能够返回对象的一个引用和一个获得该实例的方法(必须是静态方法,通常使用getInstance()函数)。单例的实现主要是通过以下两个步骤:(1)将该类的构造函数定义为私有的,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;(2)在该类内提供一个静态函数,当我们调用这个函数时,如果类持有的引用不为空就返回这个引用,如果类持有的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。
class Singleton
{
private:
Singleton()
{}
//禁止拷贝
Singleton(const Singleton&)
{}
//禁止赋值
Singleton& operator = (const Singleton&)
{}
static Singleton instance;
static pthread_mutex mutex;
public:
static Singleton getInstance()
{
pthread_mutex_lock(&mutex);
if (instance == NULL)
{
instance = new Singleton();
}
pthred_mutex_unlock(&mutex);
return instance;
}
};