美文网首页
单例模式

单例模式

作者: StevenHD | 来源:发表于2020-11-21 17:39 被阅读0次

    单例模式的功能——取代全局变量,来实现共享,实战是全局配置文件,不需要每次使用这个文件的时候都这个文件。(因为n多个地方都需要用这个配置文件,单例模式让它只读一次就可以了,接下来使用这个全局配置文件的时候,就会方便很多)


    • 之所以要使用static,是因为构造器和析构器都是private的,不能再通过【创建类对象的方式】访问类内部的东西了,因此只能通过static的方式。

    创建类对象的方式一般有2种,第一种是A a,第二种是new A

    一、普通的单例模式(懒汉)

    • 第一次用到类实例的时候才去实例化
    #include <iostream>
    
    using namespace std;
    
    
    class Singleton
    {
    public:
        static Singleton* getInstance()
        {
            if (_ins == nullptr) _ins = new Singleton;
            return _ins;
        }
    
    private:
        static Singleton * _ins;
    
        Singleton() {}
        Singleton(const Singleton&) {}
        Singleton& operator=(const Singleton&) {}
        ~Singleton() {}
    };
    
    Singleton* Singleton::_ins = nullptr;
    
    int main()
    {
        // Singleton a;
        Singleton *ps = Singleton::getInstance();
        Singleton *ps2 = Singleton::getInstance();
        if (ps == ps2) cout << "ps == ps2" << endl;
    
        return 0;
    }
    

    二、饿汉的单例模式(线程安全)

    • 单例类的定义的时候就进行实例化
    #include <iostream>
    
    using namespace std;
    
    
    class Singleton
    {
    public:
        static Singleton* getInstance()
        {
            return _ins;
        }
    
    private:
        static Singleton * _ins;
    
        Singleton() {}
        Singleton(const Singleton&) {}
        Singleton& operator=(const Singleton&) {}
        ~Singleton() {}
    };
    
    // 初始化
    Singleton* Singleton::_ins = new Singleton();
    
    int main()
    {
        // Singleton a;
        Singleton *ps = Singleton::getInstance();
        Singleton *ps2 = Singleton::getInstance();
        if (ps == ps2) cout << "ps == ps2" << endl;
    
        return 0;
    }
    

    三、线程安全的懒汉模式——多线程加锁

    • 懒汉模式的基础上,在判断对象_ins是否是null前,加了一个
    • if (_ins == nullptr)是一个【读操作】
      性能差是因为每次不管哪个线程调用getInstance()都会执行一次加锁和释放锁
    #include <iostream>
    #include <mutex>
    
    using namespace std;
    
    
    class Singleton
    {
    private:
        static Singleton * _ins;
        static mutex _lock;
        static mutex lock_;
    
        Singleton() {}
        Singleton(const Singleton&) {}
        Singleton& operator=(const Singleton&) {}
        ~Singleton() {}
    
    public:
        static Singleton* getInstance()
        {
            lock_guard<mutex> guard(_lock);
            if (_ins == nullptr) _ins = new Singleton();
            return _ins;
        }
    };
    
    // 初始化
    Singleton* Singleton::_ins = nullptr;
    
    int main()
    {
        return 0;
    }
    

    四、线程安全的懒汉模式——双重检查锁+垃圾回收

    #include <iostream>
    #include <mutex>
    
    using namespace std;
    
    
    class Singleton
    {
    private:
        static Singleton * _ins;
        static mutex _lock;
    
    
        Singleton() {}
        Singleton(const Singleton&) {}
        Singleton& operator=(const Singleton&) {}
        ~Singleton() {}
    
    public:
        static Singleton* getInstance()
        {
            if (_ins == nullptr)
            {
                lock_guard<mutex> guard(_lock);
                if (_ins == nullptr) _ins = new Singleton();
                //_ins = new Singleton();
            }
            return _ins;            
        }
        
        class CGarbo
        {
        public:
            ~CGarbo()
            {
                if (Singleton::_ins) delete Singleton::_ins;
            }
        };
        
        static CGarbo garbo;
    };
    
    // 初始化
    Singleton* Singleton::_ins = nullptr;
    Singleton::CGarbo garbo;
    
    int main()
    {
        return 0;
    }
    

    五、单例模式的实战

    • 自定义一个数据文件com.cof
    • 有3个类A, B, C同时调用Config生成对象
    • 得到的数据是一样的,相当于单例完成了全局变量的工作,但是单例比全局变量好——
      图解

    单例不需要销毁,因为单例只会产生一个对象, 在程序结束的时候就会销毁。

    相关文章

      网友评论

          本文标题:单例模式

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