单例模式

2020-11-21  本文已影响0人  StevenHD

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


创建类对象的方式一般有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;
}

五、单例模式的实战

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

上一篇下一篇

猜你喜欢

热点阅读