意图:保证一个类仅有一个实例,并提供一个全局访问点
效果:
1 实现对唯一实例的受控访问
2 是对全局变量的一种改进。避免了存储唯一实例的全局变量污染命名空间
3 不仅可以实现单例,还可以实现N例,即允许可变数目的实例,还可以实现单件注册表
代码:
#include <iostream>
using namespace std;
class Singleton
{
private:
static Singleton* mInstance;
private:
Singleton() {}
Singleton(const Singleton&);
public:
static Singleton* GetInstance()
{
if(NULL == mInstance) //惰性初始化(懒汉式)
mInstance = new Singleton();
return mInstance;
}
static void FreeInstance()
{
if(NULL != mInstance)
delete mInstance;
}
};
Singleton * Singleton::mInstance = NULL;
int main()
{
Singleton* a = Singleton::GetInstance();
Singleton* b = Singleton::GetInstance();
if(a == b)
cout << "两个对象的地址都为" << (void*)a << endl;
Singleton::FreeInstance();
return 1;
}
注1:可以将单件改造成单件注册器,在字符串名字和单件之间建立映射,当Instance需要一个单件时,它参考注册表,根据名字请求单件,思想和代码都很简单,代码略
注2:注意多线程环境中需要使用双重检查锁定机制来保证正确的单例,伪码如下:
static Singleton* GetInstance()
{
if(NULL == mInstance)
{
lock();
if(NULL == mInstance)
mInstance = new Singleton();
unlock
}
return mInstance;
}
实现二:
#include <iostream>
using namespace std;
class Singleton
{
private:
static Singleton mInstance;
int i;
Singleton(int m=0) :i(m){}
Singleton(const Singleton&);
public:
static Singleton* GetInstance()
{
return &mInstance;
}
};
Singleton Singleton::mInstance(1); //初始化
int main()
{
Singleton* a = Singleton::GetInstance();
Singleton* b = Singleton::GetInstance();
if(a == b)
cout << "两个对象的地址都为" << (void*)a << endl;
return 1;
}
相关模式:很多模式,比如Abstract Factory、Builder都可以使用Singleton实现