设计模式之单例模式

引言

在现实生活中,有许许多多的职位,是有且仅有一个人能任职的,以确保这个职位是独一无二的。在程序中,也有很多类需要进行"计划生育",比如Windows系统的回收站,以及很多游戏里面的独一无二的一些BOSS或者成就、称号之类的。今天的单例设计模式就是在做这么一件事。

简单介绍

单例设计模式的作用在于让某个类仅产生一个实例对象,且提供该对象的功能接口给使用者。它有多种实现方法,但最核心的思想不外乎三点:
(1)构造函数私有化
(2)获取接口静态公开化
(3)唯一实例静态私有化
这里讲解一下这三点的作用:
(1)让外部使用者不能够产生额外的实例对象
(2)由于外部不能产生额外的实例对象,因此不能在获取到实例对象之前,访问到类的任何接口,而调用static方法不需要产生实例,所有需要提供一个公共的static方法来让用户获取实例对象(或产生实例对象并返回)。
(3)私有化使得外部只能通过static方法来获取实例对象,静态化的主要目的是方便该实例的初始化。
只要做到以上三点,能够达到外部只能获取一个实例对象的目的,就可以说实现了单例模式,简单的单例UML图如下所示:
在这里插入图片描述
话不多说,上测试代码。

单例类的定义

懒汉式单例,即在使用时才产生实例对象,相关代码如下:

//三要素 构造函数私有化  获取接口静态公开化  唯一实例静态私有化
class Singleton1;
using Ptr = shared_ptr<Singleton1>;
//懒汉式 线程不安全 需要加锁
class Singleton1 {
private:
	Singleton1() {};
	Singleton1(Singleton1& s) = delete;
	Singleton1& operator=(Singleton1& s) = delete;
public:
	void Play()
	{
		cout << "Singleton1.Playing................." << endl;
	}

	static Ptr getInstance() {
		if (!Instance)
		{
			lock_guard<mutex>auto_lock(m_mutex);
			if (!Instance)
			{
				Instance = shared_ptr<Singleton1>(new Singleton1);
			}
		}
		return Instance;
	}
private:
	static Ptr Instance;
	static mutex m_mutex;
};

饿汉式单例,即定义好类就直接产生实例对象,相关代码如下:

//饿汉式 
class Singleton2 {
public:

	~Singleton2() {
		std::cout << "Singleton - destructor." << std::endl;
	}

	static Singleton2* getInstance() {
		return m_instance;
	}

	void use() const {
		std::cout << "Singleton2 - in use." << std::endl;
	}


private:
	Singleton2() {}
	Singleton2(Singleton2&) = delete; 
	Singleton2& operator=(const Singleton2&) = delete; 
	static Singleton2* m_instance;
};

全部代码如下:

#include<iostream>
#include<string>
#include<mutex>
#include<memory>

using namespace std;
//三要素 构造函数私有化  获取接口公开静态化  唯一实例静态私有化
class Singleton1;
using Ptr = shared_ptr<Singleton1>;
//懒汉式 线程不安全 需要加锁
class Singleton1 {
private:
	Singleton1() {};
	Singleton1(Singleton1& s) = delete;
	Singleton1& operator=(Singleton1& s) = delete;
public:
	void Play()
	{
		cout << "Singleton1.Playing................." << endl;
	}

	static Ptr getInstance() {
		if (!Instance)
		{
			lock_guard<mutex>auto_lock(m_mutex);
			if (!Instance)
			{
				Instance = shared_ptr<Singleton1>(new Singleton1);
			}
		}
		return Instance;
	}
private:
	static Ptr Instance;
	static mutex m_mutex;
};

//初始化静态成员
Ptr Singleton1::Instance = nullptr;
mutex Singleton1::m_mutex;


//饿汉式 
class Singleton2 {
public:

	~Singleton2() {
		std::cout << "Singleton - destructor." << std::endl;
	}

	static Singleton2* getInstance() {
		return m_instance;
	}

	void use() const {
		std::cout << "Singleton2 - in use." << std::endl;
	}


private:
	Singleton2() {}
	Singleton2(Singleton2&) = delete; 
	Singleton2& operator=(const Singleton2&) = delete; 
	static Singleton2* m_instance;

};
//直接new 
Singleton2* Singleton2::m_instance = new Singleton2();

int main()
{
	Ptr singleton1 = Singleton1::getInstance();
	singleton1->Play();

	Singleton2* s = Singleton2::getInstance();
	s->use();
	

	system("pause");
	return 0;
}

对于单例模式的实现,还有许多反式,不管怎样实现,其中心思想依旧是上面所讲的三点。预告:下节将讲述抽象工厂模式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱你是长久之计~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值