设计模式-单件模式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、Singleton


前言

提示:这里可以添加本文要记录的大概内容:

面向对象很好的解决了抽象问题,但必不可少的要付出一定的代价。
在软件系统中,经常有一些特殊的类,必须保证他们在系统中质询才一个实例,才能保证他们逻辑的正确性以及良好的效率。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Singleton

  • 构造函数必须是私有的,不能不写,C++会默认生成public的构造函数和拷贝构造函数;
  • 默认关闭赋值操作、拷贝构造和右值;
  • public里面声明静态指针和静态函数方法,返回这个类唯一实例指针;
class Singleton
{
private:
    Singleton();
    Singleton(const Singleton &other)=delete;
    Singleton &operator=(const Singleton &other) = delete;
    Singleton(Singleton &&other) = delete;
    Singleton &operator=(Singleton &&other) = delete;
    ~Singleton();

public:
    static Singleton *getInstance();
    static Singleton *m_instance;
}

// 初始化指针为nullptr
Singleton *Singleton::m_instance = nullptr;

// 线程非安全版本, 多线程可能会创建两个以上实例
Singleton *Singleton::getInstance()
{
    if (m_instance == nullptr)
    {
        m_instance = new Singleton();
    }
    return m_instance;
}

// 线程安全版本, 但锁的代价过高
Singleton *Singleton::getInstance()
{
    Lock lock;
    if (m_instance == nullptr)
    {
        m_instance = new Singleton();
    }
    return m_instance;
}

// 双检查锁, 但由于内存读写recorder不安全
Singleton *Singleton::getInstance()
{
    if (m_instance == nullptr)
    {
        Lock lock;
        if (m_instance == nullptr)
        {
            m_instance = new Singleton();
        }
    }

    return m_instance;
}

// C++ 11版本之后的跨平台实现 (volatile)
std::atomic<Singleton *> Singleton::m_instance;
std::mutex Singleton::m_mutex;
Singleton *Singleton::getInstance()
{
    Singleton *instance = m_instance.load(std::memory_order_relaxed);
    std::atomic_thread_fence(std::memory_order_acquire); // 获取内存defence, 保证CPU没有reorder优化
    if (instance == nullptr)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        instance = m_instance.load(std::memory_order_relaxed);
        if (instance == nullptr)
        {
            instance = new Singleton();
            m_instance.store(instance, std::memory_order_release); //释放内存defence
        }
    }
    return instance;
}

你可能感兴趣的:(设计模式,设计模式,单例模式,c++)