Singleton—对象创建型模式
意图:保证一个类只有一个实例。对一些类来说,只有一个实例是很重要的。虽然系统中有许多打印机,但却只应该有一个printer spooler,只应该有一个文件系统和一个窗口管理器。
Singleton模式有许多优点:
1)对唯一实例的受控访问
2)缩小名空间
3)允许对操作和表示的精化
4)允许可变数目的实例
5)比类操作更灵活
《设计模式》书中对单例模式的c++ 定义:
class Singleton{
public:
static Singleton* getInstance(){
if(ptrInstance==NULL)
ptrInstance=new Singleton();
return ptrInstance;
}
private:
Singleton(){}
static Singleton *ptrInstance;
};
因为构造函数是私有的,所以在这种实现方式中,用户访问唯一实例的方法只有getInstance()成员函数,getInstance()使用了懒惰初始化,即它的返回值是这个函数首次被创建时的值。
但这种实现方式有两个缺点:
(1)ptrInstance指针在何时被释放
(2)线程安全的问题:由于构造函数Singleton()可以被多次访问,所以当多个线程访问时可能创建的值是不同的。
对于问题(1),解决的方式是利用静态成员变量,在程序结束时会被系统自动析构
class Singleton{
public:
static Singleton* getInstance(){
if(ptrInstance==NULL)
ptrInstance=new Singleton();
return ptrInstance;
}
private:
Singleton(){}
static Singleton *ptrInstance;
class Garbo{
public:
~Garbo(){
if(Singleton:ptrInstance)
delete Singleton::ptrInstance;
}
};
static Garbo garbo;//定义一个静态变量,程序结束时会自动析构
};
对于问题(2),解决的方法是加锁
if(ptrInstance==NULL){
pthread_mutex_lock(&mutex);
if(ptrInstance==NULL)
ptrInstance=new Singleton();
pthread_mutex_unlock(&mutex);
}
C++ 11中更好的方式是使用静态方法,保证创建和销毁都只有一次。
class Singleton{
public:
static Singleton& getInstance(){
static Singleton intance;
return instance;
}
private:
Singleton() {}
Singleton(Singleton const &)=delete;
void operator=(Singleton const&)=delete;
};
保证Singleton的构造函数是私有的,是默认copy构造函数和赋值构造函数是无效的,防止copy发生,以保证是一个singleton