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

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

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

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

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

//饿汉式单例

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. MySQL相关知识

    字符串拼接 select * from tablename where mydata like CONCAT(CURDATE(), '%') limit 3 这里concat是字符串拼接, conca ...

  2. IntelliJ idea 中使用Git

    1.要使用GitHub,首先你需要下载一个Git(地址:http://windows.github.com/)这里使用的是for Windows,然后安装完成会得到如下的一个目录:

  3. 【HDOJ】3473 Minimum Sum

    划分树解.主席树解MLE. /* 3473 */ #include <iostream> #include <sstream> #include <string> ...

  4. Android开发之多媒体编程之加载大分辨率图片

    Android中图片占用内存的大小=图片的总像数*每个像数占用的大小. Android保存图片像素信息使用ARGB,意思是每个像素占用4个字节. 以分辨率为2400*3200的图片来说,加载到Andr ...

  5. Web开发之tomcat配置及使用(环境变量设置及测试,一个简单的web应用实例)

    Tomcat的配置及测试: 第一步:下载tomcat,然后解压到任意盘符 第二步:配置系统环境变量 tomcat解压到的D盘 (路径为: D:\tomcat), 配置环境变量: 启动tomcat需要两 ...

  6. Scrapy在win7 32位的安装及依赖包

    Scrapy,一个网络爬虫的框架,首先第一步肯定是安装. 参考网上的文章. 安装过程中需要用到pip工具,请自行安装. 1.安装python 这个是必须的,既然都用到scrapy了,肯定已经安装了py ...

  7. 谈数据库索引和Sqlite中索引的使用

    要使用索引对数据库的数据操作进行优化,那必须明确几个问题:1.什么是索引2.索引的原理3.索引的优缺点4.什么时候需要使用索引,如何使用围绕这几个问题,来探究索引在数据库操作中所起到的作用. 1.数据 ...

  8. Entityframework常用命令

    Enable-Migrations 启用Migration数据迁移 Add-Migration migrationname 添加一个migration Update-Database –TargetM ...

  9. compass和sass很好的两篇文章

    Sass是一种"CSS预处理器",可以让CSS的开发变得简单和可维护.但是,只有搭配Compass,它才能显出真正的威力. 本文介绍Compass的用法.毫不夸张地说,学会了Com ...

  10. Self-Paced Training (1) - Introduction to Docker

    helloworld: wget -qo- https://get.docker.com/ | sh sudo docker run hello-world sudo usermod -aG dock ...