一.概念

单例模式:其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。

  1. class CSingleton
  2. {
  3. //公有的静态方法,来获取该实例
  4. public:
  5. static CSingleton* GetInstance()
  6. {
  7. if ( m_pInstance == NULL )  //判断是否第一次调用
  8. m_pInstance = new CSingleton();
  9. return m_pInstance;
  10. }
  11. //私有构造函数,防止实例化
  12. private:
  13. CSingleton(){};
  14. //私有静态指针变量,指向类的唯一实例
  15. private:
  16. static CSingleton * m_pInstance; //声明一个静态成员
  17. };
  18. CSingleton* CSingleton::m_pInstance = NULL; //定义并初始化静态数据成员
  19. int main()
  20. {
  21. CSingleton* ps1 = CSingleton::GetInstance();
  22. CSingleton* ps2 = CSingleton::GetInstance();
  23. CSingleton* ps3 = ps1->GetInstance();
  24. CSingleton & ps4 = * CSingleton :: GetInstance();
  25. if (ps1 == ps2)
  26. {
  27. cout<< "ps1 = ps2"<<endl;
  28. }
  29. if (ps1 == ps3)
  30. {
  31. cout<< "ps1 = ps3"<<endl;
  32. }
  33. if (&ps4 == ps1)
  34. {
  35. cout<< "ps1 = ps4"<<endl;
  36. }
  37. return 0;
  38. }

单例模式通过类本身来管理其唯一实例,唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全局访问。

用户访问唯一实例的方法只有
GetInstance() 成员函数。如果不通过这个函数,任何创建实例的尝试都将失败,因为类的构造函数是私有的。

有一点要注意:一定要加上
CSingleton* CSingleton::m_pInstance = NULL; 这一句,不然的话编译会出错,因为这一句才是变量定义。

二.单例类CSingleton 有以下特征

它有一个指向唯一实例的静态指针m_pInstance,并且是私有的;

它有一个公有的函数,可以获取这个唯一的实例,并且在需要的时候创建该实例;

它的构造函数是私有的,这样就不能从别处创建该类的实例。

三.存在的问题

1.m_pInstance
指向的空间什么时候释放呢?

如果在类的析构行为中有必须的操作,比如关闭文件,释放外部资源,那么上面的代码无法实现这个要求。我们需要一种方法,正常的删除该实例。

不合理的解决方法:

在程序结束时调用
GetInstance(),并对返回的指针掉用 delete操作。这样做可以实现功能,但不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用
GetInstance 函数。也就是说释放操作由使用者来管理,而不是由类本身来管理,这违背了类的单一职责的原则,这是不合理的。

2. 该实例的析构函数什么时候执行?

上面的类里为什么没有析构函数,其实即便你加上析构函数也是可以的,但是这个析构函数不会被执行的。因为你的实例是 new 出来的,所以只有 delete 时,才会调用析构函数,但是在哪里调用 delete 呢!?这又回到了上面的问题。

一种妥善的方法:

  1. class CSingleton
  2. {
  3. public:
  4. static CSingleton* GetInstance()
  5. {
  6. static CSingleton instance; //静态局部变量
  7. return &instance;
  8. }
  9. private:
  10. CSingleton() {}; //构造函数
  11. };

局部静态对象实例 instance 是第一次调用 GetInstance() 时被构造,一直保持活动状态直到应用程序终止,与动态分配对象不同,静态对象当应用程序终止时被自动销毁掉,所以就不必再手动销毁实例了。

当然这里,可以加上析构函数来处理你想要的操作。

这样做的要点有以下几点:

1. 静态变量在内存中只有一份,从而保证了单例模式中单一实例的要求。

2. 静态变量在程序终止时会被自动销毁,从而保证了空间正常释放。

设计模式C++描述----01.单例(Singleton)模式的更多相关文章

  1. JavaScript 设计模式之----单体(单例)模式

    设计模式之--单体(单例)模式 1.介绍 从本章开始,我们会逐步介绍在JavaScript里使用的各种设计模式实现,在这里我不会过多地介绍模式本身的理论,而只会关注实现.OK,正式开始. 在传统开发工 ...

  2. 漫谈设计模式(二):单例(Singleton)模式

    1.前言 实际业务中,大多业务类只需要一个对象就能完成所有工作,另外再创建其他对象就显得浪费内存空间了,例如web开发中的servlet,这时便要用到单例模式,就如其名一样,此模式使某个类只能生成唯一 ...

  3. ① 设计模式的艺术-01.单例(Singleton)模式

    单例模式为何要出现 在工作过程中,发现所有可以使用单例模式的类都有一个共性,那就是这个类没有自己的状态,换句话说,这些类无论你实例化多少个,其实都是一样的. 如果我们不将这个类控制成单例的结构,应用中 ...

  4. Android与设计模式——单例(Singleton)模式

    概念: java中单例模式是一种常见的设计模式.单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类仅仅能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. ...

  5. JAVA中实现单例(Singleton)模式的八种方式

    单例模式 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例. 基本的实现思路 单 ...

  6. 【Java学习笔记之三十】详解Java单例(Singleton)模式

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  7. 设计一个线程安全的单例(Singleton)模式

    在设计单例模式的时候.尽管非常easy设计出符合单例模式原则的类类型,可是考虑到垃圾回收机制以及线程安全性.须要我们思考的很多其它.有些设计尽管能够勉强满足项目要求,可是在进行多线程设计的时候.不考虑 ...

  8. 单例Singleton模式的两种实现方法

    在设计模式中,有一种叫Singleton模式的,用它可以实现一次只运行一个实例.就是说在程序运行期间,某个类只能有一个实例在运行.这种模式用途比较广泛,会经常用到,下面是Singleton模式的两种实 ...

  9. Java设计模式透析之 —— 单例(Singleton)

    写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像f ...

随机推荐

  1. 2019年十大开源WEB应用防火墙点评

    2019年十大开源WEB应用防火墙点评 随着WEB应用的爆炸式成长和HTTPS加密的普及,针对网络应用层的攻击,像SQL注入.跨站脚本攻击.参数篡改.应用平台漏洞攻击.拒绝服务攻击等越来越多,传统的防 ...

  2. Idea插件之IdeTalk

    前言 随着越来越多的公司与Java工程师,逐步从Eclipse过度到Idea,安装相应的插件可能会成倍的增加工作效率. IDETalk是由JetBrains的工程师开发的一款代码级的协同工具,主要是为 ...

  3. Centeos7搭建selenium+Chrome浏览器

    博主主要是用来更新爬虫Cookie 环境安装 python3 安装selenium pip3 install selenium 安装chrome浏览器+chromedriver驱动 一.配置yum源 ...

  4. 十大排序算法JavaScript实现总结

    花费了几周的时间断断续续的练习和模仿与使用JavaScript代码实现了十大排序算法. 里面有每种算法的动图和静态图片演示,看到图片可以自己先按照图片的思路实现一下. github中正文链接,点击查看 ...

  5. navicat安装及其简单使用

    一.安装 下载地址:https://pan.baidu.com/s/1bpo5mqj 下载完之后,直接解压出来就能用,看一下解压之后的目录: 双击打开下面这个文件(可以把它添加一个桌面快捷方式,或者添 ...

  6. mui中判断是点击还是滑动

    判断和滑动是两种触发方式 滑动分为四种,上下左右(swipeup,swipedown,swipeleft,swiperight) 点击分为两种,点击和双击,一般用单机(tap) 根据自己不同的需求进行 ...

  7. B-概率论-极大似然估计

    [TOC] 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblogs.com/nickchen121/ ...

  8. 从零开始入门 K8s | Kubernetes 网络概念及策略控制

    作者 | 阿里巴巴高级技术专家  叶磊 一.Kubernetes 基本网络模型 本文来介绍一下 Kubernetes 对网络模型的一些想法.大家知道 Kubernetes 对于网络具体实现方案,没有什 ...

  9. The Largest Clique UVA - 11324

    题文:https://vjudge.net/problem/UVA-11324 题解: 这个题目首先可以发现,只要是一个强连通分量,要么都选,要么都不选,将点权看成强连通分量的点数,所以这个题目就转化 ...

  10. 局部敏感哈希LSH(Locality-Sensitive Hashing)——海量数据相似性查找技术

    一. 前言     最近在工作中需要对海量数据进行相似性查找,即对微博全量用户进行关注相似度计算,计算得到每个用户关注相似度最高的TOP-N个用户,首先想到的是利用简单的协同过滤,先定义相似性度量(c ...