单例模式的C++实现(懒汉模式和饿汉模式的详细讲解和实现)


前言

提示:单例模式的出现。由于在某些场景中你最多而且必须有一个对象存在的情况,比如,监控摄像头对象,他在监控开启后只能有一个监控对象,单例模式就应运而生。


提示:以下是我对单例模式的理解

一、单例模式的概念

1.2单例模式的分类

单例模式:主要分为懒汉模式和饿汉模式。饿汉模式呢顾名思义比较饥渴,它会在程序加载过程中将对象进行初始化出来。懒汉模式会在程序运行阶段将对象初始化出来。两者的区别

1.2懒汉和饿汉的利弊

	懒汉模式的缺点:在加载时就会初始化对象,比较浪费内存,容易产生垃圾对象。
				由于其在加载时就会实例化对象,没有达到懒加载的效果。
	懒汉模式的优点:线程安全,不用加锁,效率较高。会在调用GetInstance前产生实例化对象,
				 对象	创建早。
	懒汉模式缺点:只有加锁才能保证多线程的安全性问题。而加锁会影响运行效率。
				实现难度相较于饿汉较大
	懒汉模式的优点:线程安全,懒加载,在第一次调用GetInstance的时候才会实例化对象。减少内存浪费。

二、代码实现

1.饿汉模式

饿汉模式

#include<iostream>
using namespace std;
//饿汉模式需要将构造函数,拷贝构造函数,赋值运算符的重载函数进行一个
//删除或者是私有化,定义一个静态成员变量,让他在程序加载时进行实例化对象
class Singleton {
public:
	static  Singleton& GetInstance() {
	//返回在程序加载时就实例化出的对象
		return sgl;
	}
private:
	static Singleton sgl; //定义一个静态成员变量
private:
//将其构造,拷贝构造,赋值运算符重载私有化
	Singleton() {}
	Singleton(Singleton&) = delete; //C++11新特性
	Singleton& operator=(Singleton&) = delete; //C++11新特性
};
//在类里面进行定义的静态成员变量需要在类外面进行实例化
Singleton Singleton::sgl;

2.懒汉模式

#include<iosteam>
#include<mutex>
using namespace std;
class Singleton {
public:
	static Singleton* GetInstance() {
		if (sgl == nullptr) {//lock外的判空,
			//是因为获取锁,是很浪费时间的,
			//获取锁之外还有一层判断,
			//那么在第二次获取单例对象的时候,
			//lock外的if判断发现指针已经非空,就不会再获取锁了,
			//直接返回了对应的对象
			mutex_t.lock();
			if (sgl == nullptr) {//lock里面判断一次,
			//因为可能有多个线程在lock处等待,
			//一个成功之后,会将m_psl设置为非空,
			//这样下个线程就算拿到lock资源,
			//再进去发现指针非空就离开了
				sgl = new Singleton();
			}
			//这样双层检测,即保证了对象创建的唯一性,又减少了获取锁浪费的时间和资源
			mutex_t.unlock();
		}
		return sgl;
	}
	//创建内部类让其在程序结束后将创建的单例销毁
	class CGarbo {
		~CGarbo() {
			delete Singleton::sgl;
		}
	};
private:
	static Singleton* sgl; //定义单例对象指针
	static mutex mutex_t; //定义锁
	static CGarbo gc; //定义内部类对象
private:
//将其构造拷贝构造和赋值运算符重载全部私有化
	Singleton() {}
	Singleton(Singleton&) = delete;
	Singleton& operator=(Singleton&) = delete;
};
//类外对其静态成员变量进行一个初始化
Singleton* Singleton::sgl = nullptr;
mutex Singleton::mutex_t;
Singleton::CGarbo Singleton::gc;

懒汉模式的双if判断有对https://blog.csdn.net/andrewgithub/article/details/108966947
的参考。


总结

我只是对我学到的东西进行了一个简单的总结。希望各位大佬多多指出错误和不足。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值