原文:http://blog.csdn.net/oohaha_123/article/details/25190833

单例模式

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。

如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。(摘自 刘伟主编 .设计模式 .北京市 :清华大学出版社 ,2011 :134-135 .)

单例模式的特点有3个:

1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

Singleton 模式包含的角色只有一个,就是Singleton 。Singleton 拥有一个私有构造函数,确保用户无法用过 new 直接实例化它。除此之外,该模式中包含一个静态私有成员变量 instance 与静态公有方法 Instance()。Instance 方法负责检验并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。

测试代码如下:

  1. /* C++单例模式 */
  2. #include<iostream>
  3. using namespace std;
  4. class Singleton
  5. {
  6. private:
  7. Singleton() //构造函数是私有的
  8. {
  9. cout<<"Creat Singleton."<<endl;
  10. }
  11. static Singleton* m_instance;
  12. public:
  13. static Singleton* GetInstance()
  14. {
  15. if(m_instance == NULL)  //判断是否为第一次调用
  16. m_instance = new Singleton();
  17. return m_instance;
  18. }
  19. };
  20. Singleton* Singleton::m_instance = NULL;
  21. int main()
  22. {
  23. Singleton* p1 = Singleton::GetInstance();
  24. Singleton* p2 = p1->GetInstance();
  25. Singleton* p3 = Singleton::GetInstance();
  26. Singleton &ref = *Singleton::GetInstance();
  27. cout<<p1<<endl;
  28. cout<<p2<<endl;
  29. cout<<p3<<endl;
  30. cout<<&ref<<endl;
  31. }

测试结果如下图:


从测试结果图中可以看到,main 函数创建了4次 Singleton 类实例,但真正只在第一次调用了构造函数,且4次创建均返回相同的指针,这说明 GetInstance() 使用懒惰初始化,也就是说它的返回值是当这个函数首次被访问时被创建的

C++编程练习(14)-------“单例模式”的实现的更多相关文章

  1. [.net 面向对象编程基础] (14) 重构

    [.net 面向对象编程基础] (14) 重构 通过面向对象三大特性:封装.继承.多态的学习,可以说我们已经掌握了面向对象的核心.接下来的学习就是如何让我们的代码更优雅.更高效.更易读.更易维护.当然 ...

  2. 《Unix 网络编程》14:高级 I/O 函数

    高级 I/O 函数 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ...

  3. 泛函编程(14)-try to map them all

    虽然明白泛函编程风格中最重要的就是对一个管子里的元素进行操作.这个管子就是这么一个东西:F[A],我们说F是一个针对元素A的高阶类型,其实F就是一个装载A类型元素的管子,A类型是相对低阶,或者说是基础 ...

  4. Linux Shell编程(14)——内部变量

    内建变量影响Bash脚本行为的变量.$BASHBash二进制程序文件的路径 bash$ echo $BASH /bin/bash$BASH_ENV该环境变量保存一个Bash启动文件路径,当启动一个脚本 ...

  5. Linux系统编程(14)——shell常用命令

    1. ls命令 ls命令是列出目录内容(ListDirectory Contents)的意思.运行它就是列出文件夹里的内容,可能是文件也可能是文件夹. "ls -l"命令已详情模式 ...

  6. CC++初学者编程教程(14) Redhat linux安装Oracle12c

    1选择虚拟机的设置 2 设置共享文件夹 3 使用共享文件夹向导 4 选择主机路径 5 启用文件共享 6 设置好文件共享以后,关闭虚拟机的设置 7 开启虚拟机 8 登陆 9输入密码 10 安装vmwar ...

  7. UNIX高级环境编程(14)文件IO - O_DIRECT和O_SYNC详解 < 海棠花溪 >

    春天来了,除了工作学习,大家也要注意锻炼身体,多出去运动运动.  上周末在元大都遗址公园海棠花溪拍的海棠花.   进入正题. O_DIRECT和O_SYNC是系统调用open的flag参数.通过指定o ...

  8. pta 编程题14 Huffman Codes

    其它pta数据结构编程题请参见:pta 题目 题目给出一组字母和每个字母的频数,因为哈夫曼编码不唯一,然后给出几组编码,因为哈夫曼编码不唯一,所以让你判断这些编码是否符合是哈夫曼编码的一种. 解题思路 ...

  9. Java中的构造函数——通过示例学习Java编程(14)

      作者:CHAITANYA SINGH 来源:https://www.koofun.com//pro/kfpostsdetail?kfpostsid=25 构造函数是用来初始化新创建的对象的代码块. ...

随机推荐

  1. Linux入门视频

    为了方便新手学习Linux,本人专门录制了以下Linux初级视频方便学习,本系列多媒体教程已完成的博文: 轻松学习Linux之入门篇 http://chenguang.blog.51cto.com/3 ...

  2. Spark给我们带来了什么惊喜?

    Spark的一站式解决方案有很多的优势,具体如下.(1)打造全栈多计算范式的高效数据流水线     Spark支持复杂查询. 在简单的“map”及“reduce”操作之外,Spark还支持SQL查询. ...

  3. ESB 客户端调用 处理类

    esb package com.isoftstone.synchronize.entrance; import java.io.File; import java.text.SimpleDateFor ...

  4. UDP广播问题

    http://bbs.csdn.net/topics/390218123 Broadcast Address(广播地址)是专门用于同时向网络中所有工作站进行发送的一个地址.在使用TCP/IP 协议的网 ...

  5. qq邮箱发送

    454 Authentication failed, please open smtp flag first!用QQ邮箱测试报错 我用QQ邮箱测试javamail发送邮件的功能,用户名密码设置正确,却 ...

  6. 找回使用过的QQ头像

    多么渴望那双眼睛能在万紫千红中发现自己:然而眼睛从来就不曾对自己留意:于是换种落寞再次接受垂直打击:然后然后的然后尼玛再换个逗比的头像证明老资无所谓老资无所谓嘿嘿: 我们换头像的时候,发现之前的一个最 ...

  7. Dell商用台式机、笔记本、服务器800电话

    戴尔Optiplex商用台式机 售后服务电话 800-858-0950 选1选2选2 戴尔Latitude商用笔记本 售后服务电话 800-858-0950 选1选3选2 戴尔服务器PowerEdge ...

  8. jquery easyui-linkButton获取和设置按钮text并且解决火狐不支持innerText的方法

    <a href="javascript:test" id="btn" class="easyui-linkbutton" iconCl ...

  9. 10个经典的Java main 方法面试题

    1. 不用main方法如何定义一个类? 不行,没有main方法不能运行Java类. 在Java 7之前,你可以通过使用静态初始化运行Java类.但是,从Java 7 开始就不行了. 2. main() ...

  10. InitializingBean和init-method

    [spring的InitializingBean的 afterPropertiesSet 方法 和 init-method配置的 区别联系] InitializingBean Spring的Initi ...