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

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

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

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

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

//饿汉式单例

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. 分布式事务的管理--atomikos

    在一些业务场景及技术架构下,跨库的事务时不可避免的,这时候如何统一管理事务,保证事务的强一致性是整个系统稳定.可用基石.一些中间件如tuxedo.cics就是凭借这个能力占据了金融.电信.银行等很大的 ...

  2. 115. Distinct Subsequences

    题目: Given a string S and a string T, count the number of distinct subsequences of T in S. A subseque ...

  3. Flash Builder 4.6 基本设置

    Flash Builder 4.6 字体修改 打开Flash Builder4.6 -> 窗口 -> 首选项 -> 左边目录选择常规 -> 外观 -> 颜色和字体 -&g ...

  4. python学习笔记八--动态类型

    一.变量,对象,引用: 1. 变量: 2. 对象:均包含了一个头部信息,有以下两部分内容 a.对象的数据类型, b.引用计数器:纪录当前引用货指向该对象的数量,一旦计数器被清零,该对象的内存空间就会被 ...

  5. 【HDOJ】3386 Final Kichiku “Lanlanshu”

    数位DP.需要注意的是需要特殊处理前导0,另外连续的==匹配,不要计重了,尽量贪心的匹配掉. /* 3886 */ #include <iostream> #include <sst ...

  6. C++ 空类默认产生成员函数

    class Empty { Empty(){...} //默认构造函数 ~Empty(){...} //默认析构函数 Empty(const Empty&){...} //拷贝构造函数 Emp ...

  7. 以CTE表达式实现MSSQL的字符串分割函数

    ALTER     FUNCTION [dbo].[Split] (@sep varchar(2), @s varchar(512))RETURNS tableASRETURN (    WITH P ...

  8. 【聚类算法】谱聚类(Spectral Clustering)

    目录: 1.问题描述 2.问题转化 3.划分准则 4.总结 1.问题描述 谱聚类(Spectral Clustering, SC)是一种基于图论的聚类方法——将带权无向图划分为两个或两个以上的最优子图 ...

  9. 解决android手机sd卡安装pak后直接打开,按home键异常问题

    if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) { finish(); return; }

  10. CSS3 Transitions, Transforms和Animation使用简介与应用展示

    CSS3 Transitions, Transforms和Animation使用简介与应用展示 by zhangxinxu from http://www.zhangxinxu.com本文地址:htt ...