zoukankan      html  css  js  c++  java
  • 剑指offer 面试题2:实现Singleton模式

    转自:https://blog.csdn.net/liang19890820/article/details/61615495

    Singleton 的头文件(懒汉式/饿汉式公用):

    // singleton.h
    #ifndef SINGLETON_H
    #define SINGLETON_H
    
    #include <iostream>
    #include <mutex>
    using namespace std;
    
    // 单例 - 懒汉式/饿汉式公用
    class Singleton
    {
    public:
        static Singleton* GetInstance();
        static void DestoryInstance()//手动释放资源
        {
            if (m_pSingleton != NULL) {
                delete m_pSingleton;
                m_pSingleton = NULL;
            }
        }
    private:
        Singleton() {}  // 构造函数(被保护)
    
    private:
        static Singleton *m_pSingleton;  // 指向单例对象的指针
        static mutex m_mutex;  //
    };
    
    #endif // SINGLETON_H

    懒汉式

    懒汉式的特点:

    • Lazy 初始化
    • 非多线程安全

    优点:第一次调用才初始化,避免内存浪费。 
    缺点:必须加锁(在“线程安全”部分分享如何加锁)才能保证单例,但加锁会影响效率。

    在懒汉式下,如果使用多线程,会出现线程安全隐患。为了解决这个问题,可以引入双检锁 - DCL 机制。

    // singleton.cpp
    #include "singleton.h"
    
    // 单例 - 懒汉式(双检锁 DCL 机制)
    Singleton *Singleton::m_pSingleton = NULL;
    mutex Singleton::m_mutex;
    
    Singleton *Singleton::GetInstance()
    {
        if (m_pSingleton == NULL) {
            std::lock_guard<std::mutex> lock(m_mutex);  // 自解锁
            if (m_pSingleton == NULL) {
                m_pSingleton = new Singleton();
            }
        }
        return m_pSingleton;
    }

    饿汉式

    饿汉式的特点:

    • 非 Lazy 初始化
    • 多线程安全

    优点:没有加锁,执行效率会提高。 
    缺点:类加载时就初始化,浪费内存。

    // singleton.cpp
    #include "singleton.h"
    
    // 单例 - 饿汉式
    Singleton *Singleton::m_pSingleton = new Singleton();
    
    Singleton *Singleton::GetInstance()
    {
        return m_pSingleton;
    }

    面试比较好的解法:

    // singleton.h
    #ifndef SINGLETON_H
    #define SINGLETON_H
    
    #include <iostream>
    
    using namespace std;
    
    // 单例 - 自动释放
    class Singleton
    {
    public:
        static Singleton* GetInstance();
    
    private:
        Singleton() {}  // 构造函数(被保护)
    
    private:
        static Singleton *m_pSingleton;  // 指向单例对象的指针
    
        // GC 机制
        class GC
        {
        public:
            ~GC()
            {
                // 可以在这里销毁所有的资源,例如:db 连接、文件句柄等
                if (m_pSingleton != NULL) {
                    cout << "Here destroy the m_pSingleton..." << endl;
                    delete m_pSingleton;
                    m_pSingleton = NULL;
                }
            }
            static GC gc;  // 用于释放单例
        };
    };
    
    #endif // SINGLETON_H
    // main.cpp
    #include "singleton.h"
    
    Singleton::GC Singleton::GC::gc; // 重要
    
    int main()
    {
        Singleton *pSingleton1 = Singleton::GetInstance();
        Singleton *pSingleton2 = Singleton::GetInstance();
    
        cout << (pSingleton1 == pSingleton2) << endl;
    
        return 0;
    }
  • 相关阅读:
    timeStamp(时间戳) 事件属性
    解析Javascript事件冒泡机制(转) 本文转自:http://blog.csdn.net/luanlouis/article/details/23927347
    stopPropagation()阻止事件的冒泡传递
    JavaScript for...in 循环
    js中的内置对象(还没怎么看)
    python 数组的切片
    python 文件的读写
    python 基础数据类型作业
    pycharm本地git拉代码使用方法
    数据库日常练习
  • 原文地址:https://www.cnblogs.com/parzulpan/p/11255553.html
Copyright © 2011-2022 走看看