应用场景
当一些需要被重复使用的类,为了避免在使用过程中不断创建释放,产生内存碎片,可采用单例来解决该问题
实现思路
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
需注意点
1.防止外部能够创建该类以及其它类继承该类,构造函数私有化,赋值运算符重载私有化。
2.保证线程安全,防止多个线程同时创建该类对象,加锁。
具体实现
总共有五种,懒汉式、饿汉式、加锁式、双重锁定式、局部静态对象式
1.懒汉式:在调用GetInstance接口时才实例化,所以在多线程情况,可能会出现同时进行实例化的情况
2.饿汉式:在静态变量初始化的时候就进行实例化,不会出现线程安全问题
3.加锁式:就是在懒汉式的基础上加锁,确保同一时刻仅有一条线程实例化该对象,但这种每次都会加锁,
有点影响性能
4.双重锁定式:双重判断,避免每次都要加锁。
5.静态局部对象式:其实就是利用的静态局部对象的生命周期和作用域,静态局部对象的作用域是局部可见,
生命周期和全局变量一致,存储在全局变量区域,程序结束时才销毁。
1. 懒汉式
懒汉式
class CSingletonLazy
{
public://提供全局的接口获取单例
static CSingletonLazy* GetInstance()
{
if (!m_Instance)
{
m_Instance = new CSingletonLazy();
}
return m_Instance;
}
private://私有化构造和赋值运算符重载
CSingletonLazy() {};
CSingletonLazy(CSingletonLazy&) {};
CSingletonLazy& operator=(CSingletonLazy&) {};
private:
static CSingletonLazy* m_Instance;
};
CSingletonLazy* CSingletonLazy::m_Instance = NULL;
线程安全:否
2. 饿汉式
//饿汉式
class CSingletonHungry
{
public:
static CSingletonHungry* GetInstance()
{
return m_Instance;
}
private:
CSingletonHungry() {};
CSingletonHungry(CSingletonHungry&);
CSingletonHungry& operator=(CSingletonHungry&);
private:
static CSingletonHungry* m_Instance;
};
CSingletonHungry* CSingletonHungry::m_Instance = new CSingletonHungry();
线程安全:是
3.加锁
class CSingletonLazy
{
public://提供全局的接口获取单例
static CSingletonLazy* GetInstance()
{
// Lock() //加锁,具体未实现
if (!m_Instance)
{
m_Instance = new CSingletonLazy();
}
// ReleaseLock()
return m_Instance;
}
private://私有化构造和赋值运算符重载
CSingletonLazy() {};
CSingletonLazy(CSingletonLazy&) {};
CSingletonLazy& operator=(CSingletonLazy&) {};
private:
static CSingletonLazy* m_Instance;
};
CSingletonLazy* CSingletonLazy::m_Instance = NULL;
4.双重锁定
class CSingletonLazy
{
public://提供全局的接口获取单例
static CSingletonLazy* GetInstance()
{
if(!m_Instance)
{
// Lock() //加锁,具体未实现
if (!m_Instance)
{
m_Instance = new CSingletonLazy();
}
// ReleaseLock()
}
return m_Instance;
}
private://私有化构造和赋值运算符重载
CSingletonLazy() {};
CSingletonLazy(CSingletonLazy&) {};
CSingletonLazy& operator=(CSingletonLazy&) {};
private:
static CSingletonLazy* m_Instance;
};
CSingletonLazy* CSingletonLazy::m_Instance = NULL;
5.静态局部对象(C++11)
class CSingleton
{
public:
static CSingleton* GetInstance()
{
static CSingleton s_obj;
return &s_obj;
}
private:
CSingleton() {};
public: //C++11
CSingleton(CSingleton&) = delete;
CSingleton& operator = (CSingleton&) = delete;
};
线程安全:是
参考文献链接
1. 单例模式实现 stack overflow
2. 单例何时使用 stack overflow
3. 大佬分析 知乎
4. 源码链接 git
5. 源码链接 git