C++ 设计模式 之 单例模式 【开发学习笔记】

文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。


资料仅供学习交流使用。
作者:Aliven888

1、背景

1.1、为什么要学习设计模式

设计模式是一种知识和经验,和编程语言无关。熟练的掌握各种设计模式后,我们(程序猿)可以快速的去识别一个系统的骨骼框架,也可以快速的搭建出一个健壮的系统。

设计模式也可以理解为我们(程序猿)心中的一张张蓝图,握住他们,就可能成为一位有大局观的构架师,松开它们,可能注定只能成为一名默默无闻 的码农。

1.2、什么是单例模式

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式,,可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

如果希望在系统中某个类的对象只存在一个,单例模式显然是最好的解决方案。

1.3、单例模式的特点

1、某个类只有一个实例(并非绝对,一些特殊的情况下可以存在多个)。
2、它必须自行创建这个实例。
3、它必须向整个系统提供这个实例(即整个系统都可以直接使用该实例)。

1.4、使用场景

1、日志打印:每一个软件系统都会存在一个日志打印功能,而且在软件系统中很多位置都在调用该打印功能,此时为了保证日志文件的安全写入,可以使用单例模式实现。

2、设备管理系统:在设备管理系统中,不管有多少个设备,那么设备的管理类就只会存在一个。

1.5、单例模式的实现思路

要求类只能返回同一个对象的引用,和一个获取给对象的方法。

单例模式的实现主要分为以下两个步骤:

1、将该类的构造方法定义为私有方法,这样其他的代码就无法调用该构造函数去实例化新的对象了。

2、该类提供一个静态的方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,否则就先创建,然后再返回。

1.6、单例模式的UML:

在这里插入图片描述

1.7、单例模式常用的实现方式

1、懒汉模式
2、线程安全模式
3、饿汉模式

2、单例模式常用模式介绍

2.1、懒汉模式

定义: 懒汉,顾名思义,就是很懒,不到使用的时候,是不会想起来去实例化它的。也就是说在第一次使用到类实例的时候才回去实例化。

特点: 以空间换时间,是非线程安全的。

懒汉模式代码演示:

//.h
class CSingletonPattern
{
public:
	static CSingletonPattern *getInstance();  //创建实例对象接口函数
	void DestoryInstance();  //销毁实例对象接口函数

	~CSingletonPattern();

private:
	CSingletonPattern();

private:
	static CSingletonPattern *m_instance;
};


//.cpp
CSingletonPattern::CSingletonPattern()
{
}

CSingletonPattern::~CSingletonPattern()
{
    //销毁对象
	DestoryInstance();
}

//初始化对象
CSingletonPattern *CSingletonPattern::m_instance = NULL;

 //创建实例对象
CSingletonPattern* CSingletonPattern::getInstance() 
{
	//对象不为空,则创建对象
	if (NULL == m_instance)
	{
		m_instance = new CSingletonPattern();
	}
	return m_instance;
}
void CSingletonPattern::DestoryInstance()  //销毁实例对象
{
	delete m_instance;
	m_instance = NULL;
}

2.2、线程安全模式

我们前面说懒汉模式在线程上是不安全的,那我要怎么实现呢?
相比想到这里就行明白了,既然线程资源不安全,那么我们就加个线程锁控制一下如何。

代码演示:

//.h
class CSingletonPattern
{
public:
	static CSingletonPattern *getInstance();  //创建实例对象
	void DestoryInstance();  //销毁实例对象

	~CSingletonPattern();

private:
	CSingletonPattern();

private:
	static CSingletonPattern *m_instance;
	static mutex m_mutex;  //定义互斥锁
};

//.cpp
CSingletonPattern::CSingletonPattern()
{
}

CSingletonPattern::~CSingletonPattern()
{
	DestoryInstance();
}

//初始化对象
CSingletonPattern *CSingletonPattern::m_instance = NULL;
mutex CSingletonPattern::m_mutex;

CSingletonPattern* CSingletonPattern::getInstance()  //创建实例对象
{
	//对象不为空,则创建对象
	if (NULL == m_instance)
	{
		m_mutex.lock();
		//这个为了防止在加锁的过程中,系统中的两个位置同时调用,这里需要在判断一次
		//以保证加锁成功后进来的只有一个位置调用。
		if(NULL == m_instance)
		{
			m_instance = new CSingletonPattern();
		}
		m_mutex.unlock();
	}
	return m_instance;
}
void CSingletonPattern::DestoryInstance()  //销毁实例对象
{
	delete m_instance;
	m_instance = NULL;
}

2.3、饿汉模式

定义: 顾名思义,饿的时候才会饥不择食。在系统启动时,对象就被实例化创建。

特点: 以空间换时间,是线程安全的。

//.h
class CSingletonPattern
{
public:
	static CSingletonPattern *getInstance();  //创建实例对象接口函数
	void DestoryInstance();  //销毁实例对象接口函数

	~CSingletonPattern();

private:
	CSingletonPattern();

private:
	static CSingletonPattern *m_instance;
};


//.cpp
CSingletonPattern::CSingletonPattern()
{
}

CSingletonPattern::~CSingletonPattern()
{
    //销毁对象
	DestoryInstance();
}

//初始化对象
CSingletonPattern *CSingletonPattern::m_instance = new CSingletonPattern();

 //获取实例对象
CSingletonPattern* CSingletonPattern::getInstance() 
{
	return m_instance;
}
void CSingletonPattern::DestoryInstance()  //销毁实例对象
{
	delete m_instance;
	m_instance = NULL;
}

2.4、优缺点对比

1、懒汉方式:在访问量较少的情况下使用,以时间换空间,但是线程不安全。

2、饿汉方式:在访问量较多的情况下使用,以空间换时间,线程安全;

3、饿汉方式反而是最懒的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值