动机
- 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。
- 如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例
- 这应该是类设计者的责任,而不是使用者的责任
设计方法
- 将默认构造和拷贝构造私有化
- 内部维护一个(私有)静态对象指针
- 对外提供公有静态函数来访问指针
实现代码
class Singleton{
private:
Singleton();
Singleton(const Singleton& other);
private:
static Singleton* m_instance;
public:
static Singleton* getInstance();
};
Singleton* Singleton::m_instance=nullptr;
//线程非安全版本
Singleton* getInstance(){
if(m_instance == nullptr){
m_instance = new Singleton();
}
}
//线程安全版本,但锁的代价过高
Singleton* getInstance(){
Lock lock;
if(m_instance == nullptr){
m_instance = new Singleton();
}
}
//双检查锁,但由于内存读写reorder不安全
Singleton* Singleton::getInstance(){
if(m_instance == nullptr){
Lock lock;
if(m_instance == nullptr){
m_instance == new Singleton();
}
}
}
其他线程安全实现方式
- Effective C++中直接返回局部静态对象的方式
Singleton& Singleton::getInstance()
{
//局部静态特性的方式实现单实例
static Singleton signal;
return signal;
}
//代码一运行就初始化创建实例,本身就线程安全
Singleton* Singleton::m_instance = new Singleton();
Singleton* Singleton::getInstance()
{
return m_instance;
}
template<typename T>
class Singleton{
public:
static T& getinstance()
{
pthread_once(&once_control, Singelton::init);
return *value;
}
private:
Singleton();
Singleton(const Singleton& sin);
static void init()
{
value = new T();
}
private:
pthread_once_t once_control;
static T* value;
};
template<typebame T>
pthread_once_t Singleton::once_control = PTHREAD_ONCE_INIT;
T* Singleton::value = NULL;