设计模式 - 单例模式的5种实现方法

应用场景

当一些需要被重复使用的类,为了避免在使用过程中不断创建释放,产生内存碎片,可采用单例来解决该问题

实现思路

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

需注意点

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值