• 单例模式(singleton pattern)


    单例模式很好理解,就是只允许创建该类的一个实例。

    经典版

    class Singleton {
    public:
        static Singleton& getInstance() {
            static Singleton instance;
            return instance;
        }
    private:
        Singleton() {}
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
    };
    • 构造函数声明为private,则只有Singleton类的代码才能调用构造函数。
    • 利用局部静态变量达到实例只有一个的要求。
    • 局部静态变量的另一个优点是lazy initialization,只有在第一次调用getInstance()时才创建该变量。
    • getInstance()返回的是对局部静态变量的引用。如果返回的是指针,getInstance()的调用者很可能会误认为他要检查指针的有效性,并负责销毁。

    可能有人要说上面的实现不是线程安全的。

    的确,在C++11之前不是,但是在C++11中却是线程安全的。

    因为新的C++标准规定:当一个线程正在初始化一个变量的时候,其他线程必须得等到该初始化完成以后才能访问它。

    if control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

    那要是不允许使用C++11呢?那就加锁喽。

    static Singleton& getInstance() {
            lock();     
            static Singleton instance;
            unlock();   
            return instance;
        }

    DCL版(double-checked locking)

    class Singleton {
    private:
        static Singleton *instance;
        Singleton() {};
    public:
        static Singleton* getInstance() {
            if (instance == NULL)
            {
                lock();
                if (instance == NULL)
                    instance = new Singleton;
                unlock();
            }
            return instance;
        }
    };
    Singleton* Singleton::instance = NULL;

    第一次check的目的是为了只在实例不存在的情况下才进行加锁操作。

    第二次check的目的是为了确认在加锁之后,实例是否存在。如果存在就不需要new了。

    关于instance = new Singleton;这句,又涉及到CPU指令重排的问题,什么volatile啊,memory barrier啊,内容太多,记不住了。

    eager initialization

    class Singleton {
    private:
        static Singleton *instance;
        Singleton() {};
    public:
        static Singleton* getInstance() {
            return instance;
        }
    };
    Singleton* Singleton::instance = new Singleton;

    reference:

    C++ 线程安全的单例模式

    面试中的Singleton

    C++中多线程与Singleton的那些事儿

    单例模式(Singleton)及其C++实现

  • 相关阅读:
    FR #3题解
    L3-005. 垃圾箱分布
    L2-004. 这是二叉搜索树吗?
    L2-002. 链表去重
    L1-009. N个数求和
    L3-003. 社交集群
    L3-004. 肿瘤诊断
    L2-001. 紧急救援
    L3-002. 堆栈
    L2-007. 家庭房产
  • 原文地址:https://www.cnblogs.com/gattaca/p/4758851.html
Copyright © 2020-2023  润新知