2019独角兽企业重金招聘Python工程师标准>>>

今天中午看到一个面试题,是这样的,“怎样设计一个类,使其只能有一个实例”,知道设计模式的程序员可能很快就能解决这个问题,就是Singleton模式。这里我说说Singleton模式吧!

单实例设可能是使用最广泛的设计模式。其思想意图是保证一个类只有一个实例,并且提供类对象的全程访问。单实例对象应用的范围很广:如GUI应用必须是单鼠标,MODEM的联接需要一条且只需要一条电话线,操作系统只能有一个窗口管理器,一台PC连一个键盘。本文将讨论如何用C++实现单实例模式,并解释如何优化单线程应用的设计。

设计方案

使用全程对象能够保证方便地访问实例,但是不能保证只声明一个对象-也就是说除了一个全程实例外,仍然能创建相同类的本地实例。单实例模式通过类本身来管理其唯一实例,这种特性提供了问题的解决办法。唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全程访问。唯一实例类Singleton在静态成员函数中隐藏创建实例的操作。习惯上把这个成员函数叫做Instance(),它的返回值是唯一实例的指针。Singleton的定义如下:

class Singleton 
{
public:
static Singleton* Instance();
protected:
Singleton();
Singleton(const Singleton&);
Singleton& operator= (const Singleton&);
private:
static Singleton* pinstance;
};

你还可以创建诸如Mouse,FileManager,Scheduler等为名字的类并声明相应的成员。为了保证用户不能创建类的本地实例,Singleton的构造器是赋值操作符,构造函数的副本被声明为protected。类中还声明了一个私有的静态实例指针。当第一次调用静态函数Instance()时,它创建唯一实例,将实例地址赋值给pinstance,然后返回这个地址。在每次并发调用中,Instance()也将只返回这个地址。

下面是类的实现:

Singleton* Singleton::pinstance = 0;// 初始化指针
Singleton* Singleton::Instance () 
{
if (pinstance == 0) // 是第一次调用吗?

pinstance = new Singleton; // 创建唯一实例
}
return pinstance; // 唯一实例的地址
}
Singleton::Singleton() 

//... 实现必要的实例初始化
}

用户访问唯一实例的方法只有Instance()成员函数。如果不通过这个函数,任何创建实例的尝试都将失败,因为类的构造函数是被保护的。Instance()使用懒惰初始化,也就是说它返回的值是当这个函数被首次访问时被创建的。这是一种防弹设计-所有Instance()之后的调用都返回相同实例的指针:

Singleton *p1 = Singleton::Instance();
Singleton *p2 = p1->Instance();
Singleton & ref = * Singleton::Instance();

虽然本文的例子针对的是单实例,但对Instance()稍加修改,这个设计模板便可适用于可变多实例情况。如一个类允许最多五个实例。

优化Singleton类,使之适用于单线程应用

Singleton使用操作符new为唯一实例分配存储空间。因为new操作符是线程安全的,在多线程应用中你可以使用此设计模板。但是有一个缺陷:就是在应用程序终止之前必须手工用delete摧毁实例。否则,不仅导致内存溢出,还要造成不可预测的行为,因为Singleton的析构函数将根本不会被调用。而通过使用本地静态实例代替动态实例,单线程应用可以很容易避免这个问题。以下是与上面的Instance()稍有不同的实现,这个实现专门用于单线程应用:

Singleton* Singleton::Instance () 
{
static Singleton inst;
return &inst;
}

本地静态对象实例inst是第一次调用Instance()时被构造,一直保持活动状态直到应用程序终止。指针pinstance变得多余并可以从类定义中删除掉。与动态分配对象不同,静态对象当应用程序终止时被自动销毁掉,所以就不必再手动销毁实例了。

转载于:https://my.oschina.net/mavericsoung/blog/174149

单实例设计模式的实现相关推荐

  1. Singleton设计模式(单实例)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. 深入浅出单实例Singleton设计模式

    深入浅出单实例Singleton设计模式 陈皓 前序 单实例Singleton设计模式可能是被讨论和使用的最广泛的一个设计模式了,这可能也是面试中问得最多的一个设计模式了.这个设计模式主要目的是想在整 ...

  3. 设计模式(三)单实例模式

    引言 对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务:一个系统只能有一个窗口管理器或文件系统:一个系统只能有一个计时工具或ID(序号)生 ...

  4. python基础知识整理 第七节:单例设计模式、异常、模块、包、制作模块、文件

    1.单例设计模式 单例设计模式就是为对象在内存中分配空间的时候,永远只会返回一个唯一的固定的内存空间.这样就能保证在内存中这个类的对象只有唯一的一份,这个就叫做单例.(为对象分配空间使用的是内置方法_ ...

  5. 单例设计模式详解。。。。。。。。。。。

    public class Demo01 { public static void main(String[] args) { // TODO Auto-generated method stub /* ...

  6. java软件设计模式只单例设计模式

    概述 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计 ...

  7. 单例设计模式singleton

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

  8. Python单例设计模式

    (1)为什么使用设计模式? 使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. (2)单例设计模式概念 让类创建的对象只有唯一的一个实例,即每次执行  类名() 返回的对象,内存地 ...

  9. java单例设计模式

    单例模式的概念 单例类只有一个实例,并且只由自己创建,实例化后向整个系统提供自己的实例. 单例设计模式主要分为2种:懒汉式和饿汉式.2者的区别在于初始化的时间不同. 像线程池,缓存,日志等都被设计成单 ...

最新文章

  1. Nginx 为什么这么快?
  2. 万字详文告诉你如何做 Code Review
  3. power designer 设计数据库生成到oracle数据库
  4. GetMemeory(char *p);GetMemeory(char **p);char* GetMemeory()用法!
  5. github可视化_Cesium数据可视化-仓储调度系统可视化部分(附github源码)
  6. java基础(八) 深入解析常量池与装拆箱机制
  7. python脚本自动运行失败_解决Python中定时任务线程无法自动退出的问题
  8. yii---where or该如何使用
  9. Nsight 调试 Caffe
  10. REVERSE-PRACTICE-BUUCTF-22
  11. 面试官系统精讲Java源码及大厂真题 - 31 AbstractQueuedSynchronizer 源码解析(下)
  12. Mr.J--谈谈CSS和Html(font)
  13. easyui datagrid 列隐藏和显示
  14. wordpress and theme
  15. Win10卸载微软sql服务器,卸载 SQL Server Management Studio
  16. 基于MATLAB实现四阶龙格库塔法求解一、二阶微分方程实例
  17. solidworks二次开发 学习日记--1 开发方式
  18. 「360企业安全云」上线,免费护航中小微企业数字化建设
  19. Flutter路由管理和页面参数的传递(获取返回)
  20. ChatGPT APK 安卓手机 安装包

热门文章

  1. 05-01 docker 介绍
  2. vscode java settings设置_兼容vscode插件的主题服务
  3. 根据序列选择自回归模型(AR、ARMA、VAR、VMA、VECH)
  4. 2021年最新UI/UE设计学习路线图
  5. 计算机等级考试在校生变成社会考生,关于开展2021年9月份全国计算机等级考试(NCRE)报名工作通知...
  6. linux ip协议号,IP协议号大全
  7. php查询锁表情况,MySQL update where in 子查询导致锁表
  8. mysql where true_在MySQL中选择查询,检查字符串或在where子句中检查是否为true?
  9. NTV Media Server G3流媒体服务器搭建经验
  10. linux cp命令 强制覆盖,Linux中使用cp命令进行强制覆盖的方法