GoF设计模式——单例模式(C++实现)

概念

单例模式(Singleton Pattern)是一种创建型设计模式,是使用最广泛的设计模式之一。其作用是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
单例模式的写法有很多种,懒汉式、饿汉式等,其中对于多线程场景,也有多种方法,双检锁头、atomic类等。本章讲的是一种更优雅的写法,这种方法也被称为Meyers’ Singleton。即使用函数内的 local static 对象。这样,只有当第一次访问getInstance()方法时才创建实例。
当然,这种方法只有在c++11之后才是线程安全的。C++11规定,在一个线程开始local static 对象的初始化后到完成初始化前,其他线程执行到这个local static对象的初始化语句就会等待,直到该local static 对象初始化完成,保证了内部静态变量的线程安全性。
在这里插入图片描述

代码示例

class Singleton
{
    
    
private:
    Singleton() {
    
    };
    ~Singleton() {
    
    };

    double m_fValue = 9.9;
public:
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&)= delete;

    static Singleton* getInstance()
    {
    
    
        static Singleton instance;
        return &instance;
    }

    double getValue()
    {
    
    
        qDebug()<<"m_fValue:"<<m_fValue<<'\n';
        return m_fValue;
    }

};

int main(int argc, char *argv[])
{
    
    
    Singleton* instance = Singleton::getInstance();
    instance->getValue();
}

有同学可能会思考,能否将局部静态变量定义为类的静态成员变量,这就是饿汉式的写法。虽然这种方法也是线程安全的,但是会存在另一个问题。
虽然C++规定,non-local static 对象的初始化发生在main函数执行之前,也即main函数之前的单线程启动阶段。但没有规定多个non-local static 对象的初始化顺序,尤其是来自多个编译单元的non-local static对象,他们的初始化顺序是随机的。所以如果在初始化完成之前调用 getInstance() 方法会返回一个未定义的实例。

猜你喜欢

转载自blog.csdn.net/weixin_44901043/article/details/123934926