【设计模式】单例模式 C++实现

一、概念

单例模式(Singleton): 保证一个类仅有一个实例,并提供一个访问它的全局访问点。

通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。

二、实现方法

单例模式有三种实现方法:懒汉式、双重锁定(Double-Check-Locking)、饿汉式。
单例模式的UML图

1. 懒汉式
先看代码:

class Singleton   //实现单例模式的类  
  {  
  private:  
      Singleton() {}  //私有的构造函数  
      static Singleton* instance;  //对象
  public:  
      static Singleton* GetInstance()  // 实例化创建。获得本类实例的唯一全局访问点
      {  
          if (instance == NULL) //若实例不存在,则new一个实例;否则返回已有实例 
              instance = new Singleton();  
          return instance;  
      }  
  }; 

(1)构造函数声明为private,是为了防止被外部函数实例化。
(2)内部保存一个private static的类指针保存唯一的实例,实例的动作有一个public的类方法GetInstance()实现。
(3)缺点:如果是多线程同时调用GetInstance(),则可能会创建多个实例。所以再看看双重锁定,

2. 双重锁定(改进的懒汉式)

代码如下:

class Singleton   //实现单例模式的类  
  {  
  private:  
      Singleton() {}  //私有的构造函数  
      static Singleton* instance;  //对象
  public:  
      static Singleton* GetInstance()  // 实例化创建。获得本类实例的唯一全局访问点
      {  
      	  if (instance == NULL) //先判断实例是否存在,若不存在就先加把锁
      	  {
			  Lock(); //加锁
			  if (instance == NULL) //若实例不存在,则new一个实例;否则返回已有实例 
	          {
				 instance = new Singleton();  
			  }
			  Unlock(); //解锁
		  }         
          return instance;  
      }  
  }; 

为什么加了锁之后还要判断一次 instance 是否为空呢?

我们看看这种情况:当instance为空,并且两个线程同时调用GetInstance()时,它们都会通过第一重判断instance == NULL,然后由于有锁,只能有一个线程进去,另一个线程得在外面等待,当进去的线程出来后,此时已经有实例对象了,如果没有第二重判断,那么在外等待的线程也会进去再次创建一个实例,这就不是单例了。

3.饿汉式(静态初始化)

class Singleton   //实现单例模式的类  
  {  
  private:  
      Singleton() {}  //私有的构造函数       
  public:  
      static Singleton& GetInstance()  // 实例化创建。获得本类实例的唯一全局访问点
      {   
     	  static Singleton instance;  // 实例
          return instance;  
      }  
  }; 

分析:
(1)饿汉式代码最简单,即使是多线程也是安全的。
(2)类一加载时就实例化对象,所以称之为饿汉式。而懒汉式是要在第一次被调用时才将自己实例化。
(3)所以,饿汉式要提前占用系统资源。而懒汉式有多线程的问题,需要用双重锁定来处理。具体使用哪一种模式要看具体的项目需求。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wolves_liu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值