单例模式也称单子模式、单件模式,通过单例模式可以保证系统中只有一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享

对于系统中的某些类来说,只有一个实例很重要,比如一个打印机可以有多个打印任务,但是只有一个正在工作的任务,一个系统只能有一个窗口管理器或文件系统  

  单例模式的要点有三个;1. 单例类只能有一个实例 2. 它必须自行创建这个实例 3. 它必须自行向整个系统提供提供这个实例

  从具体实现角度来说,就是以下三点: 1. 单例模式的类只提供私有的构造函数 2. 类定义中含有一个该类的静态私有对象 3. 该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象

  单例模式的一些注意点

    一 实例控制:    单例模式会阻止其他对象实例化自己的单例对象的副本,从而确保所有对象都访问唯一实例

    二 灵活性:  因为类控制实例化过程,所以类可以灵活更改实例化过程

    三 开销:   虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销,这个问题可以通过静态初始化解决此问题

            定义一个私有的静态指针m_sInstance,和一个公有的静态函数 GetInstance(),

  单例模式又分为饿汉式单例和懒汉式单例,饿汉式单例在单例类被加载时就实例化一个对象交给自己的引用;而懒汉式在调用取得实例方法的时候才会实例化对象

  单例模式的优点:

    1. 在内存中只有一个对象,节省内存空间

    2. 避免频繁的创建销毁对象,可以提高性能

    3. 避免对共享资源的多重占用

    4. 可以全局访问

  单例模式的适用场景:

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

    2. 创建对象耗时过多或者耗资源过多,但又经常用到的对象

    3. 有状态的工具类对象

    4. 频繁访问数据库或文件的对象

    5. 以及其他要求只有一个对象的场景

  在C++ 中一般都使用懒汉式单例,但懒汉式单例可能会有线程安全,异常安全问题    

  实例代码如下:    

 class CSingleton
{
private:
CSingleton() //构造函数是私有的
{
}
public:
static CSingleton * GetInstance()
{
static CSingleton *m_pInstance;
if(m_pInstance == NULL) //判断是否第一次调用
m_pInstance = new CSingleton();
return m_pInstance;
}
};

  对于拷贝构造和分配操作符如果我们不打算自定义的话,那么最好将它们也置为私有且不实现

  考虑到线程安全和异常安全,实现代码如下:

 class Lock
{
private:
CCriticalSection m_cs;
public:
Lock(CCriticalSection cs) : m_cs(cs)
{
m_cs.Lock();
}
~Lock()
{
m_cs.Unlock();
}
}; class CSingleton
{
private:
CSingleton();
CSingleton(const CSingleton &);
CSingleton& operator = (const CSingleton &); public:
static CSingleton *Getinstance();
static CSingleton *m_Instance;
static CCriticalSection cs;
}; CSingleton* CSingleton::m_Instance = ; CSingleton* CSingleton::Getinstance()
{
if(m_Instance == NULL)
{ //double check
Lock lock(cs); //用lock实现线程安全,用资源管理类,实现异常安全
//使用资源管理类,在抛出异常的时候,资源管理类对象会被析构,析构总是发生的无论是因为异常抛出还是语句块结束。
if(m_Instance == NULL)
{
m_Instance = new Singleton();
}
}
return m_Instance;
}

之所以在Instantialize函数里面对pInstance 是否为空做了两次判断,因为该方法调用一次就产生了对象,pInstance == NULL 大部分情况下都为false,如果按照原来的方法,每次获取实例都需要加锁,效率太低。而改进的方法只需要在第一次 调用的时候加锁,可大大提高效率。

设计模式之单例模式-C++的更多相关文章

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

    设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...

  2. GJM : C#设计模式(1)——单例模式

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  3. java设计模式之单例模式(几种写法及比较)

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

  4. 每天一个设计模式-4 单例模式(Singleton)

    每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...

  5. 设计模式之单例模式的简单demo

    /* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...

  6. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

  7. 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则

    加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...

  8. java 23 - 2 设计模式之单例模式

    单例模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢?  A:把构造方法私有  B:在成员位置自己创建一个对象  C:通过一个公共的方法提供访问 单例模式之饿汉式: (一进来就造对 ...

  9. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

  10. python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】

    python_way day8 一.面向对象三大特性: 多态 二.面向对象中的成员 字段.方法属性 三.成员修饰符 四.特殊成员 __init__.__doc__.__call__.__setitem ...

随机推荐

  1. P4574 [CQOI2013]二进制A+B

    传送门 思路: 本题可用数位DP来做,设 f [ i ][ a ][ b ][ c ][ j ] 表示当前枚举到(二进制下的)第i位,a' b' c'各用a,b,c了几个1,j表示最后一位是否有进位. ...

  2. L2-021 点赞狂魔

    会set的基础用法就可以A了,虽然是L2题,但是不难,代码如下,很好理解,set在这里不解释了自己去网上查一下就明白了: #include<stdio.h> #include<str ...

  3. Qt532.QString_填充字符

    1.代码: void MainWindow::on_pushButton_clicked() { QString str = "; QString str01 = str.leftJusti ...

  4. DAY3 数据类型与运算符

    一.注释 代码注释分单行和多行注释, 单行注释用#,多行注释可以用三对双引号""" """ 注释用于解释某一行代码的作用,增加代码的可读性 ...

  5. Dreamweaver 1 网页制作

    1.站点 1.1 创建站点 点击菜单栏中站点进行站点创建,输入站点名称,路径 1.2 设置图像文件夹 1.3 站点管理 站点的编辑.复制.删除 2.页面属性栏 2.1 外观 1.设置页面整体的字体.大 ...

  6. split函数

    b="aa,:bb:c,c"a1,a2,a3=b.split(":")  #以:为分隔符,分成3个字符串

  7. springBoot集成Redis遇到的坑(择库)源码分析为什么择库失败

    提示: springboot提供了一套链接redis的api,也就是个jar包,用到的连接类叫做LettuceConnectionConfiguration,所以我们引入pom时是这样的 <de ...

  8. Codeforces 233 D - Table

    D - Table 思路:dp 首先,第i列的个数肯定和第i - n列个数一样,假设[i - n + 1, i - 1] 之间的个数之和为x,那么第i列和第i-n列的个数应该是n - x 那么我们可以 ...

  9. DirectX之顶点法线的计算

    首先要明白,顶点法线存在的原因:确定灯光照射到物体表面的角度.所以一提到顶点法线,肯定要进行与灯光相关的运算了. 下面是顶点法线的计算方式 假如 A.B.C三个顶点构成一个三角形,它们对应的顶点法线分 ...

  10. 如何调节tomcat初始内存

    1.linux下调节tomcat初始内存大小 linux下tomcat的运行文件为catalina.sh,打开文件,在文件靠近顶部找到“ JAVA_OPTS ”字样,在它后面添加如下内容即可 # JA ...