专栏首页闷骚的程序员设计模式学习之单件模式

设计模式学习之单件模式

如下内容是学习《Head First 设计模式》第五部分《单件模式》所得,主要就是一些原文摘抄和少量自己的总结。

单件模式定义

单件模式确保类只有一个实例,并提供一个全局访问点。

书中示例的 C++ 实现版源码

这个 Solution 的 SingletonPattern 工程里

书中示例的类图

Visio 原图见这里:

关键代码片断

class CSingleton
{
public:
    static CSingleton* GetInstance();

    /**
    释放单例,应仅限于所有对单例对象的使用完成后调用
    */
    static void ReleaseInstance();

    void DoSomething();

private:
    CSingleton();
	CSingleton(const CSingleton&);  // private and not implemented copy constructor
	CSingleton& operator=(const CSingleton&); // private and not implemented = operator

    volatile static CSingleton* m_sUniqueInstance;
    static HANDLE m_hSync;
};
volatile CSingleton* CSingleton::m_sUniqueInstance = NULL;
HANDLE CSingleton::m_hSync = ::CreateEvent(NULL, FALSE, TRUE, NULL);

CSingleton* CSingleton::GetInstance()
{
    if (NULL == m_sUniqueInstance)
	{
        WaitForSingleObject(m_hSync, INFINITE);
        if (NULL == m_sUniqueInstance)
		{
            m_sUniqueInstance = new CSingleton();
		}
        SetEvent(m_hSync);
	}

    return (CSingleton*)m_sUniqueInstance;
}

void CSingleton::ReleaseInstance()
{
    if (0 != m_sUniqueInstance)
	{
        delete m_sUniqueInstance;
        m_sUniqueInstance = NULL;
	}

    if (NULL != m_hSync)
	{
        CloseHandle(m_hSync);
	}
}

小结

  1. 单件模式的精华是通过设计来限制一个类产生多个实例的可能性,从而满足有且仅能有一个实例的类的设计需求。
  2. 为了实现上述目标,采用了私有化构造函数和提供一个公开的获取唯一实例的接口。
  3. 要记得将复制构造函数和重载赋值运算符也声明为私有,不然类的用户仍然可以使用CSingleton ObjA(*CSingleton::GetInstance())CSingleton ObjB = *CSingleton::GetInstance())的写法来得到第二、第三甚至更多的实例对象。
  4. 为了实现多线程安全,在创建唯一实例的时候会采用多线程同步设施如临界区、事件等来保证,声明实例指针使用 volatile 关键字。
  5. 在 Java 等语言中有「同步方法」和「急切」创建实例等方式来解决多线程的问题,C++ 中貌似都不太适用,使用 volatile 加双重检查加锁相对靠谱。
  6. 记得在合适的地方释放单例以及时和正确地回收资源。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何让 HelloWorld.apk 体积最小

    按照最新 ADT 的默认设置(如下图所示)创建一个最简单的 HelloWorld 程序,会发现最后生成的 apk 文件大小就已经达到了惊人的 903KB。如果只...

    mzlogin
  • 记一个折磨了我一天半的 Bug

    最近开始学习后台开发,虽然与我以前从事的 Android 开发一样都是使用 Java 语言,但是技术栈完全不同,有太多的必备的「新」概念要去学习,而在对它们,以...

    mzlogin
  • 给 Mac 添加右键菜单「使用 VSCode 打开」

    最终的实现效果是在文件 / 文件夹上右击时,会出现菜单项「用 VSCode 打开」,点击后会启动 Visual Studio Code 打开对应的文件 / 文件...

    mzlogin
  • 【工作中学习1】两个设计模式:Singleton(单例)和 Adapter(适配器)

      好久没有写自己的学习小文章,罪过罪过。。最近本菜鸟在项目中接触到经常用到的设计模式,首先是Singleton(单例),这个相信大家都会用到很多,所以自己用代...

    宋凯伦
  • 自定义docker容器网络

    1.通过bridge 驱动创建类似前面默认的 bridge 网络: docker network create --driver bridge my_net 如...

    @凌晨
  • 解决CentOS6.4 Docker "Couldn't connect to Docker daemon ..." 问题

    安装完毕fig,并完成相应配置时执行如下命令出错(fig安装参见:http://www.fig.sh/):

    2Simple
  • VBA/VB6/VB.NET 采用金山词霸在线翻译函数(自动识别语言种类)

    巴西_prince
  • 快点进来get“推荐系统常用的推荐算法”

    ? 一、推荐系统概述和常用评价指标 1.1 推荐系统的特点 在知乎搜了一下推荐系统,果真结果比较少,显得小众一些,然后大家对推荐系统普遍的观点是: (1)重...

    小莹莹
  • python实现验证码生成显示

    py3study
  • Ubuntu配置源与安安装软件

    深浅无解

扫码关注云+社区

领取腾讯云代金券