美文网首页
11月_c++单例模式的几种写法

11月_c++单例模式的几种写法

作者: FlyingPig_ | 来源:发表于2018-11-07 16:40 被阅读14次

    0x01 单例模式简介

    单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

    实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。

    单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。

    构建方式

    懒汉方式: 指全局的单例实例在第一次被使用时构建。

    饿汉方式: 指全局的单例实例在类装载时构建。

    0x02 C++下单例模式实现的几种实现(皆是线程安全的实现)

    程序结束时释放对象

    1. 静态局部对象

    class Singleton{
        private:
            Singleton(){};  //构造函数私有
            virtual ~Singleton(){};  //析构函数私有
            Singleton(Singleton const &);  //不实现
            void operator=(Singleton const &);  //不实现
        public:
            static Singleton& getInstance(){  //获取唯一实例
                static Singleton instance;  //静态局部对象C++11可保证线程安全
                return instance;
            }
    };
    
    

    2. 静态成员对象

    class Singleton{
        private:
            Singleton(){};
            ~Singleton(){};
            Singleton(Singleton const &);
            void operator=(Singleton const &);
        public:
            static Singleton& getInstance(){
               return m_pInstance;
            }
        private:
            static Singleton m_pInstance;  //静态成员对象
    };
    
    Singleton Singleton::m_pInstance;  //类外初始化
    
    

    3. 静态对象,生成在堆中, 借助GC实现自动释放

    class Singleton{
        private:
            Singleton(){};
            ~Singleton(){};
            Singleton(Singleton const &);
            void operator=(Singleton const &);
        public:
            static Singleton* getInstance(){
                if(NULL == m_pInstance)  //Yoda conditions good ?
                    m_pInstance = new Singleton();
                return m_pInstance;
            }
        private:
            class GC{  //借助GC的析构实现内存释放
                public:
                    ~GC(){
                        if(Singleton::m_pInstance){
                            delete m_pInstance;
                        }
                    }
            };
        private:
            static Singleton* m_pInstance;
            static GC m_gc;  //GC变量
    };
    
    

    4. 随时释放对象,构建在堆中,需手动调用destroy():

    class Singleton{
        private:
            Singleton(){};
            ~Singleton(){};
            Singleton(Singleton const &);
            void operator=(Singleton const &);
        public:
            static Singleton* getInstance();
            static void destroy();  //手动调用destroy()实现内存释放
        private:
            static Singleton* m_pInstance;
            static Mutex m_Mutex;
    };
    
    Singleton* Singleton::getInstance(){  //double-check实现保证线程安全
        if(NULL == m_pInstance){
            m_Mutex.lock();  //加锁
            if(NULL == m_pInstance){
                m_pInstance = new Singleton();
            }
            m_Mutex.unlock();
        }
        return m_pInstance;
    }
    
    void Singleton::destroy(){
        if(m_pInstance){
            m_Mutex.lock();
            if(m_pInstance){
                delete m_pInstance;
                m_pInstance = NULL;
            }
            m_Mutex.unlock();
        }
    }
    

    讨论

    https://stackoverflow.com/questions/1008019/c-singleton-design-pattern

    相关文章

      网友评论

          本文标题:11月_c++单例模式的几种写法

          本文链接:https://www.haomeiwen.com/subject/ikbjxqtx.html