栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C++设计模式之单例模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++设计模式之单例模式

在软件工程中,设计模式(Design Pattern)是对软件设计普遍存在(反复出现)的各种问题,锁提出的解决防范。根据模式的目的来划分的话,GoF(Gang of Four) 设计模式可以分为以下三种类型:

1.创建型模式:用来描述“如何创建对象”,它的主要特点是“将对象的创建和使用分离”。包括单例、原型、工厂方法、抽象工厂和建造者5种模式。

2.结构型模式:用来描述如何将类或对象按照某种布局组成更大的结构。包括代理、适配器、侨接、装饰、外观、享元和组合7种模式。

3.行为型模式:用来识别对象之间的常用交流模式以及如何分配职责。包括模版方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录和解释器11种模式。

今天介绍1种常用的设计模式。

一、单例模式

单例模式(Singleton Pattern)是一种常用的模式,有一些对象我们往往只需要一个,比如全局缓存、浏览器中的window对象等。单例模式用于保证一个类仅有一个实例,并提供一个访问它的全局访问点。注意以下几点:

单例类只能由一个实例化对象。

单例类必须自己提供一个实例化对象。

单例类必须提供一个可以访问唯一实例化对象。

单例类必须提供一个可以访问唯一实例化对象的接口。

单例模式分为懒汉和饿汉两种实现方式。

懒汉单例模式

懒汉:顾名思义,不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化一个对象。在访问量较小,甚至可能不会去访问的情况下,采用懒汉实现,这是以时间换空间。

非线程安全的懒汉单例模式


//懒汉式一般实现:非线程安全,getInstance返回的实例指针需要delete

class Singleton {
  public:
  	static Singletion* getInstance();
  	~Singleton(){}
  
  private:
  	Singleton(){} //构造函数私有
  	Singleton(const Singleton& obj) = delete; // 明确拒绝
  	Singleton& operator=(const Singleton& obj) = delete; //明确拒绝
  
  	static Singleton* m_pSingletion; // 静态(static)成员;不是任意对象的组成部分,但由给定类的全体对象所共享的数据成员或函数成员。
};
  
  Singleton* Singleton::m_pSingleton = NULL;

	Singleton* Singleton::getInstance() {
    if (m_pSingleton == NULL) {
      	m_pSingleton = new Singleton;
    }
    
    return m_pSingleton;
  }

线程安全的懒汉单例模式

std::mutex mt;

class Singleton {
  public:
  	static Singleton* getInstance();
  private:
  	Singleton(){} // 构造函数私有
  	Singleton(const Singleton&) = delete; // 明确拒绝
  	Singleton& operator=(const Singleton&) = delete; // 明确拒绝
  	
  	static Singleton* m_pSingleton;
};
Singleton* Singleton::m_pSingleton = NULL;

Singleton* Singleton::getInstance() {
  if(m_pSingleton == NULL) {
    mt.lock();
    if(m_pSingletion == NULL) {
      m_pSingleton = new Singleton();
    }
    mt.unlock();
  }
  
  return m_pSingleton;
}

返回一个reference指向local static对象

这种单例模式实现方式多线程可能存在不确定性:任何一种non-const static对象,不论它是local或non-local,在多线程环境下“等待某事发生”都会有麻烦。解决的方法:在程序的单线程启动阶段手工调用所有reference-returning函数。这种实现方式的好处是不需要去delete它。

class Singleton{
	public:
  	static Singleton& getInstance();
  private:
  	Singleton(){}
  	Singleton(const Singleton&) = delete; //明确拒绝
  	Singleton& operator=(const Singleton&) = delete; //明确拒绝
};
  
 Singleton& Singleton::getInstance() {
    static Singleton singleton;
  	return singleton;
}

饿汉单例模式

饿汉:饿了肯定要饥不择食。所以在单例类定义的时候就进行实例化。在访问量比较大,或者访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。

// 饿汉式:线程安全,注意一定要在合适的地方去delete它
class Singleton {
	public:
		static Singleton* getInstance();
	private:
		Singleton(){} //构造函数私有
		Singleton(const Singleton&) = delete; //明确拒绝
  	Singleton& operator=(const Singleton&) = delete; //明确拒绝
  
  	static Singleton* m_pSingleton;
};

Singleton* Singleton::m_pSingleton = new Singleton();

Singleton* Singleton::getInstance() {
  return m_pSingleton;
}

应用场景:

需要频繁实例化然后销毁的对象。

创建对象时消耗过多或消耗资源过多,但又经常用到的对象。

系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/325056.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号