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

    在项目或面试中,最有可能遇到的就是单例模式,所以,能够手写一个单例模式是学习设计模式的基本功之一。

    1. 单例模式

    单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    所有的单例模式都是使用静态方法进行创建的,所以单例对象在内存中静态共享区中存储。

    应用场景(参考:《大话设计模式》):
    1) 需求:在前端创建工具箱窗口,工具箱要么不出现,出现也只出现一个
    遇到问题:每次点击菜单都会重复创建“工具箱”窗口。
    解决方案一:使用if语句,在每次创建对象的时候首先进行判断是否为null,如果为null再创建对象。

    2) 需求:如果在5个地方需要实例出工具箱窗体
    遇到问题:这个小bug需要改动5个地方,并且代码重复,代码利用率低
    解决方案二:利用单例模式,保证一个类只有一个实例,并提供一个访问它的全局访问点。

    单例模式可以分为懒汉式和饿汉式:

    • 懒汉式:在类加载时不初始化。
    • 饿汉式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。

    2. 示例:双重校验锁

    #ifndef SINGLETON_PATTERN_H
    #define SINGLETON_PATTERN_H
    
    #include <iostream>
    #include <mutex>
    
    class CSingleton
    {
    public:
        /* 删除器类 */
        class DeleteInstance
        {
        public:
            ~DeleteInstance()
            {
                std::cout << "DeleteInstance's destructor called." << std::endl;
                if (CSingleton::m_pSingleton)
                {
                    delete CSingleton::m_pSingleton;
                }
            }
        };
    
        static DeleteInstance deleteInstance;   ///< 删除器类实例
    
    public:
        /* 获取实例的全局访问点 */
        static CSingleton* GetInstance()
        {
            /* 双检锁 */
            if (nullptr == m_pSingleton)
            {
                std::lock_guard<std::mutex> lgLock(m_mutex);
                if (nullptr == m_pSingleton)
                {
                    m_pSingleton = new CSingleton();
                }
            }
            return m_pSingleton;
        }
    
        ///* destructor */
        //~CSingleton()
        //{
        //    std::cout << "CSingleton's destructor called." << std::endl;
        //    delete m_pSingleton;
        //}
    
    private:
        /* private constructor */
        CSingleton()
        {
            std::cout << "CSingleton's constructor called." << std::endl;
        }
    
        /* private copy constructor */
        CSingleton(const CSingleton&) = delete;
    
        /* private operator = */
        CSingleton& operator=(const CSingleton&) = delete;
    
    private:
        static CSingleton   *m_pSingleton;   ///< 静态实例
        static std::mutex    m_mutex;        ///< 多线程时的单例, 保证线程安全
    };
    
    /* static 成员的初始化, 这些东西最好放在CPP文件中, 以免会产生重复定义问题 */
    CSingleton*                CSingleton::m_pSingleton = nullptr;    ///< 懒汉式, 在第一次被引用时,才会实例化.
    std::mutex                  CSingleton::m_mutex;                         ///< static mutex 初始化
    CSingleton::DeleteInstance CSingleton::deleteInstance;      ///< 删除器, 在程序结束时调用析构函数, 删除 m_pSingleton.
    
    #endif // SINGLETON_PATTERN_H
    

    3. 参考

  • 相关阅读:
    疯狂学java的第32天
    疯狂学java的第31天
    疯狂学java的第30天
    疯狂学java的第29天
    疯狂学java的第28天
    javaSE_day14_抽象类
    javaSE_day13_继承、super、this
    JavaSE_day12_static关键字丶单列设计模式丶代码块
    JavaSE_day11_常用类(String类丶StringBuffer类丶StringBuilder类)
    JavaSE_day10_初识API丶常用类(Scanner丶Random丶ArrayList)
  • 原文地址:https://www.cnblogs.com/walkinginthesun/p/9505776.html
Copyright © 2011-2022 走看看