单例设计模式

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。

为什么会产生设计模式这样的东西呢?

使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

其中最具代表性的就是单例设计模式

单例设计模式

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。

在linux下曾提到过单例设计模式:

实现:

  • 饿汉模式:资源在程序初始化阶段就完成加载(空间换时间)
  • 饿汉方法实现:
  1. 采用静态方法修饰资源,所有对象共用同一份资源,程序初始化阶段完成资源加载且只被加载一次
  2. 构造函数私有化 ,保证一个类只能实例化一个对象
template <typename T>
class Singleton {static T data;Singleton(){}//构造函数私有化
public:static T* GetInstance() {return &data;}
};
  • 懒汉模式:资源在使用的时候再去加载(延迟加载)
  1. 定义对象指针,初始资源为空
  2. static修饰,共用一份资源
  3. volatite修饰 ,防止编译器过度优化
  4. 加锁保护  线程安全
  5. 二次检测,防止锁冲突
template <typename T>
class Singleton {volatite static T* inst;//定义对象指针  初始为空static std::mutex _mutex;
public:static T* GetInstance() {if(inst==NULL)//double check 二次检测,避免不为空情况依然加锁,造成锁冲突{_mutex.lock();if (inst == NULL) {inst = new T();//调用时发现为空,进行获取资源}_mutex.unlock();}return inst;}
};

总结来说,单例设计主要分为两种:

  • 饿汉模式(提前响应)
  • 懒汉模式(延迟加载)
  • 饿汉模式

在C++11标准下,饿汉模式要求:程序启动时就创建一个唯一的实例对象

要满足此条件,提前创建对象,只有将其定义为全局变量或静态变量,才会程序启动前完成创建

// 饿汉模式
// 优点:简单
// 缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。
class Singleton
{
public:
static Singleton* GetInstance()
{
return &m_instance;
}
private:
// 构造函数私有
Singleton(){};// C++11防拷贝
Singleton(Singleton const&) = delete;
Singleton& operator=(Singleton const&) = delete;
static Singleton m_instance;
};
Singleton Singleton::m_instance; // 在程序入口之前就完成单例对象的初始化

注:
1,构造函数私有  外部无法创建对象
2,通过接口  指针获取已创建对象
3,类内 定义静态成员对象,类外初始化

4,定义静态成员,静态成员定义在类内,类内可以访问私有成员函数完成构造,且静态成员存储在静态数据区,与类不为同一块存储空间

  • 懒汉模式

#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
class Singleton
{
public:static Singleton* GetInstance() {
// 注意这里一定要使用Double-Check的方式加锁,才能保证效率和线程安全if (nullptr == m_pInstance) {//第一次判断防止多次加锁导致锁冲突m_mtx.lock();if (nullptr == m_pInstance) {//第二次判断是否为空,为空则为第一次调用构造函数创建,不为空,后续都不会调用构造函数,满足对象第一次创建且仅创建一次m_pInstance = new Singleton();}m_mtx.unlock();}    return m_pInstance;}// 实现一个内嵌垃圾回收类class CGarbo {public:~CGarbo(){if (Singleton::m_pInstance)delete Singleton::m_pInstance;}};
// 定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象
static CGarbo Garbo;
private:// 构造函数私有Singleton(){};// 防拷贝Singleton(Singleton const&);Singleton& operator=(Singleton const&);static Singleton* m_pInstance; // 单例对象指针 静态成员变量,在调用构造函数前先创建进行判断static mutex m_mtx; //互斥锁
};
Singleton* Singleton::m_pInstance = nullptr;//静态成员变量类外初始化,第一次初始化为nullptr
Singleton::CGarbo Garbo;
mutex Singleton::m_mtx;
void func(int n)
{cout<< Singleton::GetInstance() << endl;
}// 多线程环境下演示上面GetInstance()加锁和不加锁的区别。
int main()
{thread t1(func, 10);thread t2(func, 10);t1.join();t2.join();cout << Singleton::GetInstance() << endl;cout << Singleton::GetInstance() << endl;
}

C++11标准下的单例设计模式相关推荐

  1. java基础—多线程下的单例设计模式的安全问题

    //多线程下的单例设计模式 class Sing {//饿汉式不存在安全问题,因为其不是线程同步的private static Sing s = new Sing();private Sing(){} ...

  2. C#基础11.2:单例设计模式

    PS:注释和讲解全在代码中 单例设计模式其实就是一个经典问题:如何设计只能有一个实例化的对象的类 //其实C++也是用的基本一模一样的方法 using System; using System.Col ...

  3. 结合Spring源码学习单例设计模式

    之前我学习了 Spring Ioc,明白了 Spring IoC 容器是一个管理Bean的容器,在Spring的定义中,它要求所有的IoC容器都需要实现接口 BeanFactory ,它是一个顶级容器 ...

  4. Java笔记017-类变量和类方法、理解main方法语法、代码块、单例设计模式、final关键字

    目录 面向对象编程(高级部分) 类变量和类方法 类变量-提出问题 传统方法解决 问题分析: 类变量快速入门 类变量内存布局 什么是类变量 如何定义类变量定义语法: 如何访问类变量 定义语法: 类变量使 ...

  5. Java查漏补缺(08)关键字:static、单例设计模式、理解main方法、类的成员之四:代码块、final关键字、抽象类、接口、内部类、枚举类、注解、包装类

    Java查漏补缺(08)关键字:static.单例设计模式.理解main方法.类的成员之四:代码块.final关键字.抽象类.接口.内部类.枚举类.注解.包装类 本章专题与脉络 1. 关键字:stat ...

  6. 单例设计模式singleton

    简单引入 单例设计模式作为最简单,最常用的设计模式.一般是这两中写法,这两种写法教科书所谓的标准写法,但是实际上存在不少问题.后面介绍标准写法,以规避这些问题. 1.懒汉式: /*** 问题在于,当多 ...

  7. GOF设计模式之1:单例设计模式

    1.单例设计模式核心作用: 保证一个类只有一个实例,并且提供了访问该实例的全局访问点 2.常见应用场景: window的任务管理器 项目中读取配置文件一般也是一个单例模式 数据库连接池的设计也是采用单 ...

  8. 第 5 章 单例设计模式

    第 5 章 单例设计模式 1.单例设计模式介绍 所谓类的单例设计模式, 就是采取一定的方法保证在整个的软件系统中, 对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法). ...

  9. JavaSE面向对象:继承、多态、Super、Object类、重写、static、final、静态成员、懒汉式、饿汉式、单例设计模式、初始化块、抽象类、抽象方法、接口

    感谢尚硅谷免费提供的视频 继承 ** 理解 ** 生活中的继承:子女继承了父母的财产或相貌或才华 java中的继承:一个类不用自己定义属性或方法,就已经具备了另一个类的属性和方法 把这种现象称为jav ...

最新文章

  1. TCP/IP总结(2)基础概念
  2. ERP 我最看重什么?
  3. android 自定义控件央视,Android自定义ViewGroup之第一次接触ViewGroup
  4. 最短路径(迪杰斯特拉算法)
  5. 50-overlay 如何实现跨主机通信?
  6. 深度学习系统相比较传统的机器学习系统,针对常见的分类问题,精度究竟能有多大提升?...
  7. 为什么计算机专业被称为宇宙机,量子计算机为何被称为宇宙中最强大的计算机...
  8. Android之back键拦截处理
  9. mysql关联表分页查询_MySQL一对多分页查询-主表关联表条件查询问题
  10. AgreementMaker:Efficient Matching for Large Real-World 翻译
  11. mysql1558错误,mysql删除用户错误ERROR 1558解决办法
  12. golang 安全的tcp server_化繁为简,写一个简单好用的server
  13. Java通过SSH实现文件上传下载功能
  14. PDFium使用分享
  15. ReadyState的五种状态详解
  16. python机器学习思维导图脑图(完整版)
  17. 一篇让你搞定word文档毕业论文/书籍格式
  18. Python将numpy(.npy文件)存储为.ply文件
  19. AM335x启动流程(BootRom- MLO-的Uboot)
  20. python实现数据可视化软件_基于Python实现交互式数据可视化的工具

热门文章

  1. NLP之TEA之CNN:利用CNN算法实现对句子分类+进行情感分析(预测句子情感)
  2. 六一儿童节,程序员对自己好一点
  3. 全球最顶级的电脑配置_世界十大饼干排行榜,全球十大最著名顶级饼干排名
  4. 那些被岁月遗忘的UNIX经典著作
  5. typeof NaN的结果是什么?
  6. 连入网络的所有计算机都必须使用,[判断题] 联入网络的所有计算机都必须使用同样的操作系统。...
  7. C语言:计算2的50次方需要多久?
  8. [Audio]硬件设备
  9. 学习编程之路的随笔 (일 )
  10. 二分查找,超详细解读与代码实现,看完不会取关