但凡成为大家公认的模式,都是有一些不可小觑的威力,今天分享一个简单的设计模式:单例模式。

单例模式用于一些只希望有一个实例的类或者只希望执行一次的操作:校长只能有一个、老板只能有一个、用户点击弹窗只希望弹出一次。用全局变量等方式也可以实现,但是多了很多判断和处理代码,并且职责模糊,类的唯一实例化是交给调用者进行判断处理的,每调用一次就要做一次判断,重复了很多工作量,如果是多线程编程,不好的同步设计更是会导致程序卡顿。

如果还在为这些重复工作苦恼,是时候着手单例模式了:设计简单、调用方便、一劳永逸。

用一句话来描述单例模式:私有化的构造函数和公有化的静态获取实例方法。

单例模式设计的示例比较简单,不做赘述:

//饿汉式单例

class singletonhungry

{

public:

static singletonhungry* GetInstance();

private:

static singletonhungry* m_Ins;

singletonhungry(){}

singletonhungry(const singletonhungry&) {}

};

//static成员的初始化在进入main函数之前完成,随程序退出而终结生命,对象在程序生命周期内一直存在且单例

singletonhungry* singletonhungry::m_Ins = new singletonhungry;

singletonhungry* singletonhungry::GetInstance()

{

return m_Ins;

};

//懒汉式单例

class singletonlazy

{

public:

static singletonlazy* GetInstance();

private:

static singletonlazy* m_Ins;

singletonlazy() {}

singletonlazy(const singletonlazy&) {}

};

singletonlazy* singletonlazy::m_Ins = NULL;

singletonlazy* singletonlazy::GetInstance()

{

if(m_Ins == NULL)

{

//仅在程序需要对象时才被加载

m_Ins = new singletonlazy;

}

return m_Ins;

};

//多线程模式的懒汉单例

class multithreadsingletonlazy

{

public:

static multithreadsingletonlazy* GetInstance();

private:

static multithreadsingletonlazy* m_Ins;

static HANDLE hMutex;

multithreadsingletonlazy() {}

multithreadsingletonlazy(const multithreadsingletonlazy& ) {}

};

multithreadsingletonlazy* multithreadsingletonlazy::m_Ins = NULL;

HANDLE multithreadsingletonlazy::hMutex = CreateMutex(NULL, FALSE, TEXT("singleton"));

multithreadsingletonlazy* multithreadsingletonlazy::GetInstance()

{

if(m_Ins == NULL)

{

WaitForSingleObject(hMutex, INFINITE);

if(m_Ins == NULL)

{

m_Ins = new multithreadsingletonlazy;

}

ReleaseMutex(hMutex);

}

return m_Ins;

}

//验证一下是否同一个实例

void foo45()

{

singletonlazy* lazy1 = singletonlazy::GetInstance();

singletonlazy* lazy2 = singletonlazy::GetInstance();

singletonhungry* hungry1 = singletonhungry::GetInstance();

singletonhungry* hungry2 = singletonhungry::GetInstance();

multithreadsingletonlazy* msl1 = multithreadsingletonlazy::GetInstance();

multithreadsingletonlazy* msl2 = multithreadsingletonlazy::GetInstance();

if(lazy1 == lazy2)

{

cout << "lazy1 equal to lazy2" << endl;

}

if(hungry1 == hungry2)

{

cout << "hungry1 equal to hungry2" << endl;

}

if(msl1 == msl2)

{

cout << "msl1 equal to msl2" << endl;

}

}

仅用了13行就完成了非常实用的单例模式,仔细想一想,还真是有点小激动呢!

小结:单例模式和简单工厂模式有一些内在的共通特性,职责内敛,由类本身负责实例,所有的外界调用者只需要打声招呼“嗨,给我一个实例”,大大减少了重复代码和错误概率,本身的实现也很简单,时时记得这个好帮手哟。

【C++深入浅出】设计模式学习之单例模式的更多相关文章

  1. C#设计模式学习笔记-单例模式随笔

    最近学习 设计模式,从单例模式入手 啥是单例模式: 要实现一个单例类的话,首先,肯定是不能让用户自行生产的,那就是说明不能让用户new,所以,就必须把构造函数设置成为私有的 因为静态变量的生命周期跟整 ...

  2. C#设计模式学习笔记-单例模式(转)

    C#设计模式学习笔记-单例模式 http://www.cnblogs.com/xun126/archive/2011/03/09/1970807.html 最近在学设计模式,学到创建型模式的时候,碰到 ...

  3. 我的设计模式学习笔记------>单例模式(Singleton)

    一.前言 有些时候,允许自由创建某个类的实例是没有意义,还可能造成系统性能下降(因为创建对象所带来的系统开销问题).例如整个Windows系统只有一个窗口管理器,只有一个回收站等.在Java EE应用 ...

  4. C#设计模式学习笔记-单例模式

    最近在学设计模式,学到创建型模式的时候,碰到单例模式(或叫单件模式),现在整理一下笔记. 在<Design Patterns:Elements of Resuable Object-Orient ...

  5. Java设计模式学习记录-单例模式

    前言 已经介绍和学习了两个创建型模式了,今天来学习一下另一个非常常见的创建型模式,单例模式. 单例模式也被称为单件模式(或单体模式),主要作用是控制某个类型的实例数量是一个,而且只有一个. 单例模式 ...

  6. Java设计模式学习01——单例模式(转)

    原地址:http://blog.csdn.net/xu__cg/article/details/70182988 Java单例模式是一种常见且较为简单的设计模式.单例模式,顾名思义一个类仅能有一个实例 ...

  7. JavaScript设计模式学习之单例模式

    一.单例模式介绍                 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问, ...

  8. 设计模式学习之单例模式(Singleton,创建型模式)(4)

    假如程序中有一个Person类,我的需求就是需要在整个应用程序中只能new一个Person,而且这个Person实例在应用程序中进行共享,那么我们该如何实现呢? 第一步: 新建一个Person类,类中 ...

  9. javascript设计模式学习之四——单例模式,缓存与对象池

    单例模式的定义:确保一个实例,并提供全局访问. 惰性单例的定义:只在需要的时候才创建对象. 在开发中,有些对象往往只需要一个,比如线程池.全局缓存.浏览器中的window对象等. java中的单例 关 ...

随机推荐

  1. R语言学习笔记:矩阵与数组(array)

    元素可以保存在多个维度的对象中,数组存储的是多维数据元素,矩阵的是数组的特殊情况,它具有两维. 创建数组的几种方法. 1. > m<-c(45,23,66,77,33,44,56,12,7 ...

  2. 转载 .htaccess文件RewriteRule语法规则

    详见: http://blog.csdn.net/scchary/article/details/40045807    # -- 位于行首时表示注释.       [F] -- Forbidden( ...

  3. 【HDOJ】4351 Digital root

    digital root = n==0 ? 0 : n%9==0 ? 9:n%9;可以简单证明一下n = a0*n^0 + a1*n^1 + ... + ak * n^kn%9 = a0+a1+..+ ...

  4. C#和.net之间的关系

    What is the difference between C# and .NET? In addition to what Andrew said, it is worth noting that ...

  5. poj3321Apple Tree(树状数组)

    http://poj.org/problem?id=3321 刚一看题以为要建一颗树 看了下讨论说dfs 这里dfs遍历时设的标号很好 一个low一个high 包含了以这一节点为根节点的子树结点的所有 ...

  6. 大四实习准备2_java异常处理_android控件练习

    2015-4-24 Java 异常处理 可以有多个catch;ArrayIndexOutOfBoundsException类是Exception类的子类RuntimeException类的一个间接子类 ...

  7. poj3666

    一道不错的dp题 就是最小修改代价,使序列变为一个非下降序或非上升(由于数据较弱直接求非下降即可,当然非上升非下降本质是一样的) 观察可得到,修改后得到的数列中的元素最后一定都在原序列中: 由此我们可 ...

  8. windows版本git的下载地址

    最后编辑时间 2016年09月01日13:13 首先需要下载msysgit,下载最新版本即可 https://git-for-windows.github.io/ 这个是源代码 https://git ...

  9. [转] C# Winform 拦截关闭按钮触发的事件

    原文 C# Winform 拦截关闭按钮触发的事件 用户关闭软件时,软件一般会给“是否确认关闭”的提示. 通常,我们把它写在FormClosing 事件中,如果确定关闭,就关闭:否则把FormClos ...

  10. NetCat简介与使用方法

    精品学习网考试频道小编应广大考生的需要,特为参加考试的考生策划了“NetCat简介与使用方法”专题等有关资料,供考生参考! 在入侵中它是最经典的工具之一 ,NetCat被所有的网络安全爱好者和研究者称 ...