#include<iostream>
using namespace std;

//【线程安全】:不管多个线程是怎样的执行顺序和优先级,或是wait,sleep,join等控制方式,
// 如果一个类在多线程访问下运转一切正常,并且访问类不需要进行额外的同步处理或者协调那么我们就认为它是线程安全的。
// 线程安全的类应当封装了所有必要的同步操作,调用者无需额外的同步。还有一点:无状态的类永远是线程安全的

//方式:
//1、懒汉式:实例用到才会加载,时间换空间,getInstance() 方法中需要使用
// 同步锁synchronized (Singleton.class) 防止多线程同时进入
// 造成 instance 被多次实例化。导致线程不安全
class CSingleton
{
public:
static CSingleton* GetInstance()
{
if ( m_pInstance == NULL )
m_pInstance = new CSingleton();
return m_pInstance;
}
private:
CSingleton(){};
static CSingleton * m_pInstance;
};
//上诉懒汉式简单,但是会存在内存泄漏的问题,new出来的东西始终没有释放


//懒汉式改进,多线程安全版本(加上了同步锁)
class Singleton
{
private:
static Singleton* m_instance;
Singleton(){}
public:
static Singleton* getInstance();
};

Singleton* Singleton::getInstance()
{
if(NULL == m_instance)
{
Lock();//借用其它类来实现,如boost
if(NULL == m_instance)
{
m_instance = new Singleton;
}
UnLock();
}
return m_instance;
}


//2、饿汉式:实例一开始就加载,空间换时间,线程安全
//但是【写法】会出现线程安全问题
class CSingleton
{
private:
CSingleton()
{
}
public:
static CSingleton * GetInstance()
{
static CSingleton instance;
return &instance;
}
};
//在饿汉式的单例类中,其实有两个状态,单例未初始化和单例已经初始化。
// 假设单例还未初始化,有两个线程同时调用GetInstance方法,这时执行 m_pInstance == NULL 肯定为真,
// 然后两个线程都初始化一个单例,最后得到的指针并不是指向同一个地方,不满足单例类的定义了,
// 所以饿汉式的写法会出现线程安全的问题!在多线程环境下,要对其进行修改。


//饿汉式改进
class CSingleton
{
private:
CSingleton()
{
}
static CSingleton *m_pInstance;
class CGarbo
{
public:
~CGarbo()
{
if(CSingleton::m_pInstance)
delete CSingleton::m_pInstance;
}
};
static CGarbo Garbo;
public:
static CSingleton * GetInstance()
{
if(m_pInstance == NULL)
m_pInstance = new CSingleton();
return m_pInstance;
}
};



//单例模式
//1、私有构造函数,2、一个类只含有一个实例,3、提供实例的访问接口
//注意:1、防止内存泄露,使用new的时候记得要释放

class Singleton
{
private:
Singleton() {};
~Singleton() {};
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
static Singleton& getInstance() {
static Singleton instance;
return instance;
}
};