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

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

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

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

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

//饿汉式单例

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. SRM589

    250: 给一个串S,可以做这样的操作,可以将串中的一种字母变成另一种字母,代价是该种字母的数量.求解的问题是,最小的代价将串S变成回文串. 根据回文关系,我们可以形成等价对应关系,a与b等价对应说明 ...

  2. windows下配置环境变量时,在cmd窗口执行配置的命令时无效的原因

    一个原因肯定就是配置错误,这个就要自己仔细去检查了,如果确信配置正确,可能是你的cmd窗口在环境变量配置之前就打开的,在配置好环境变量之后,在cmd窗口执行命令是看不到效果的,可以关掉cmd窗口再重新 ...

  3. RabbitMQ消息队列(一): Detailed Introduction 详细介绍(转)

    1. 历史 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有 ...

  4. 如何在给快满的Linux分区"无伤"扩容

    1. 首先在虚拟机设置里面设置磁盘的扩展,前提条件是该虚拟机没有快照. 2. 在虚拟机设置好以后,需要开机在系统里扩容磁盘 3. 使用 # fdisk /dev/sda 扩展磁盘,具体操作使用 m 选 ...

  5. 1628. White Streaks(STL)

    1628 题意不太好理解 求横黑条 和竖黑条共有多少个 注意1*1的情况 如果横向纵向都是1*1 算为一个 否则不算 用了下vector  枚举找下 #include <iostream> ...

  6. css揭秘之按钮的实现技巧

    <html> <title>css</title> <style> button{ padding: .3em .8em; border: 1px so ...

  7. 函数fseg_set_nth_frag_page_no

    /**********************************************************************//** Sets the page number in ...

  8. jquery 图片无缝切换

    想要和园友分享一下学习jquery的经验.总结,更希望园友提出点建议. 第一次写,有不好的地方请多多见谅! 文笔有限,很多时候不知道怎么来描述,唉.硬伤啊!!那只好多做了,贴代码... ok,废话少说 ...

  9. mac osx 升级yosemite后java出错的解决

    原文  http://www.cnblogs.com/walkerwang/p/4034152.html

  10. 【MySql存储过程】DATE_ADD用法

    定义和用法 DATE_ADD() 函数向日期添加指定的时间间隔. 语法 DATE_ADD(date,INTERVAL expr type) date 参数是合法的日期表达式.expr 参数是您希望添加 ...