2种单例模式+最好单例

单例模式

  作用及特点:单例类,顾名思义只会创建一个,例如太阳类,地球类, 一般来说单例类分为两种:懒汉模式和饿汉模式。
  因为我们的马戏团比较小,只有一个马戏团管理员,所以我们将 马戏团管理员写成单例类,其实我们在第一篇《注册工厂模式》就使用到了单例模式,不过那个单例是全局函数获取单例,这次我们使用类内定义,开一个静态接口。

线程安全懒汉单例

  懒汉模式是第一次调用接口的时候,第一次创建该单例类,因为实例化出来的是静态对象,所以只会被初始化一次。以后每次调用接口,返回值都是第一次调用时初始化的对象。

class AnimalManager
{
public:
	static GetInterface();
	
private:
	AnimalManager();
	static AnimalManager* m_animalManager;
	static std::mutex m_singleMutex;//单例模式的锁
};

  线程安全懒汉单例具体实现,它要解决的问题是,多个线程同时第一次调用接口的时候,对创建操作加锁,防止创建两份,引起内存指针混乱的问题。

AnimalManager* AnimalManager::m_animalManager = nullptr;
std::mutex AnimalManager::m_singleMutex;

AnimalManager* AnimalManager::getAnimalManager()
{
	if (nullptr == m_animalManager)
	{
		m_singleMutex.lock();
		m_animalManager = new AnimalManager;
		m_singleMutex.unlock();
	}
	return m_animalManager;
}

饿汉单例

  懒汉模式是类初始化的时候创建对象。本质上是以空间换时间,不管用不用,先登月再说。

class AnimalManager
{
public:
	static GetInterface();
	
private:
	AnimalManager();
	static AnimalManager m_animalManager;
};

具体实现

AnimalManager AnimalManager::m_animalManager;

AnimalManager* AnimalManager::getAnimalManager()
{
	return m_animalManager;
}

类内开放接口的弊端

  静态变量的初始化顺序不受声明顺序影响,受定义顺序影响,不同cpp中都有不同静态变量的定义,在我的理解是:其初始化顺序不确定。Animal.cpp中初始化静态变量s的时候调用AnimalManager的静态变量,由于静态变量的初始化顺序问题,AnimalManager中的m_animalManager还没有初始化,所以获取指针为空。解决方法就是将 AnimalManager AnimalManager::m_animalManager; 这个定义,放在初始化静态变量s之前。当然这个方法并不好。因为人为干预了初始化顺序,并且将AnimalManager的定义放在Animal的文件中也不合适。

最好的单例方式

   不适用类内接口,用全局函数的获取静态单例类,通过局部变量的特性可以保证线程安全,而且不用锁。这种获取单例的方式也是我们实际工作中用到的。

AnimalManager* GetAnimalManager()
{
	static AnimalManager s_instance;
	return &s_instance;//静态方式得到管理员类
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值