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;
    }
  • 相关阅读:
    分享自己写的基于Dapper的轻量级ORM框架~
    无屏幕和键盘配置树莓派WiFi和SSH
    树莓派配置静态IP
    给树莓派Raspbian stretch版本修改软件源
    使用powershell批量更新git仓库
    nodejs开发过程中遇到的一些插件记录
    在Ubuntu上搭建IntelliJ IDEA license server服务器
    腾讯云Ubuntu服务器修改root密码
    Elasticsearch搜索类型(query type)详解
    dubbo作为消费者注册过程分析
  • 原文地址:https://www.cnblogs.com/parzulpan/p/11255553.html
Copyright © 2011-2022 走看看