单例模式(C++)

什么是单例模式:

  • 一个类只能实例化一个对象叫做单例模式
  • 单例模式也称单子模式、单件模式,通过单例模式可以保证系统中只有一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享

单例模式的优点:

  1.  在内存中只有一个对象,节省内存空间
  2.  避免频繁的创建销毁对象,可以提高性能
  3. 避免对共享资源的多重占用
  4. 可以全局访问

单例模式的适用场景:

  1.  需要频繁实例化然后销毁的对象
  2.  创建对象耗时过多或者耗资源过多,但又经常用到的对象
  3.  有状态的工具类对象
  4. 频繁访问数据库或文件的对象
  5. 以及其他要求只有一个对象的场景

实现方式:

  • 将构造、拷贝、赋值方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
  • 在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型。
  • 定义一个静态方法返回这个唯一对象。

单例模式分为两种:饿汉/懒汉

饿汉模式:

在加载类时就已经将对象创建完毕。饿汉式的特点是一开始就加载了,因为一开始就创建了实例,所以每次用到的时候直接调用static的接口就好了。饿汉模式是线程安全的,也是因为其一开始就创建好的原因。

class Singleton
{
private:
	Singleton();   //构造、拷贝、赋值方法私有化
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
	
public:
	static Singleton* Get()
	{
		static Singleton _s;//l类对象
		return &_s;
	}
};

懒汉模式:

第一次用到类的对象的时候才会实例化。

class CSingleton
{
private:
	CSingleton();
	CSingleton(const CSingleton&);
	CSingleton& operator = (const CSingleton&);
public:
	static CSingleton* Get()
	{
		static CSingleton* _cs;
		if (_cs == nullptr)    //用到的时候才会实例化对象
			_cs = new CSingleton();
		return _cs;
	}
};

     懒汉模式在单线程的情况下没有问题,但是正是因为用到的时候才会创建对象,这也就成为了懒汉模式的缺点,若是多个线程同时首次进入Get()方法中,因为_cs == nullptr ,所以多个线程就会同时创建出_cs,就违背了单例模式的基本要求。

线程安全懒汉模式:

#include <mutex>
std::mutex _mut;
class CSingleton
{
private:
	CSingleton();
	CSingleton(const CSingleton&);
	CSingleton& operator = (const CSingleton&);
	
public:
	static CSingleton* Get()
	{
		static CSingleton* _cs;
		if (_cs == nullptr)
		{
                        //上锁保证访问的互斥性,用到了unique_lock,因为可以自动的加/解锁,但是会消耗更多的资源
			std::unique_lock<std::mutex> lock(_mut); 
                        //判断两次,加锁之后再判断,因为多个线程有可能同时进入这一步       
			if (_cs == nullptr)
			{
				_cs = new CSingleton();
			}
		}
		return _cs;
	}

};

 

两者对比:

  • 饿汉模式:加载类慢,获取对象快,线程安全 
  • 懒汉模式:加载类快,获取对象慢,线程不安全 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值