zoukankan      html  css  js  c++  java
  • 单例模式

    单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

    动机:

    对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。
    如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。
     
    要点:
    (1)某个类只能有一个实例 -- 类定义中含有一个该类的静态私有对象;
    (2)它必须自行创建这个实例 -- 单例模式的类只提供私有的构造函数;
    (3)它必须自行向整个系统提供这个实例 -- 该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
     
    优点:
    一、实例控制
    单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
    二、灵活性
    因为类控制了实例化过程,所以类可以灵活更改实例化过程。
     
    缺点:
    一、开销
    虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
    二、可能的开发混淆
    使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
    三、对象生存期
    不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。
     
    class CSingleton
    {
    private:
        CSingleton() //构造函数是私有的
        {
        }
    public:
        static CSingleton * GetInstance()
        {
            static CSingleton *m_pInstance;
            if(m_pInstance == NULL) //判断是否第一次调用
                m_pInstance = new CSingleton();
            return m_pInstance;
        }
    };

    线程安全的单例模式:

    class Singleton
    {
    private:
        static Singleton* m_instance;
        Singleton(){}
    public:
        static Singleton* getInstance();
    };
    
    Singleton* Singleton::getInstance()
    {
        if(NULL == m_instance)
        {
            Lock();//借用其它类来实现,如boost
            if(NULL == m_instance)
            {
                m_instance = new Singleton;
            }
            UnLock();
        }
        return m_instance;
    }
  • 相关阅读:
    【flutter学习】基础知识(一)
    【软件测试学习】 敏捷开发(二)
    【软件测试学习】 软件测试初步认识(一)
    【hugo】- hugo 监听浏览器切换title
    【hugo】- hugo 博客 添加鼠标单击特效
    春风十里
    一眼就能看懂的C#委托、多播委托和事件的区别与联系。
    js控制的DataGrid的URL参数不能动态刷新表格的问题
    [报错解决].net web api测试页面ajax 报错400 的问题
    [MVC]使用jquery.form.js 异步上传文件
  • 原文地址:https://www.cnblogs.com/argenbarbie/p/5398587.html
Copyright © 2011-2022 走看看