zoukankan      html  css  js  c++  java
  • 剑指Offer面试题:1.实现单例模式

    一 题目:实现单例模式Singleton

    题目:设计一个类,我们只能生产该类的一个实例。

      只能生成一个实例的类是实现了Singleton(单例)模式的类型。由于设计模式在面向对象程序设计中起着举足轻重的作用,在面试过程中很多公司都喜欢问一些与设计模式相关的问题。在常用的模式中,Singleton是唯一一个能够用短短几十行代码完整实现的模式。因此,写一个Singleton的类型是一个很常见的面试题。

    二:单例模式的几种实现方法

    (1)单线程单例模式

    // 单例模式
    class Singleton
    {
    private:
        Singleton(){}
        ~Singleton(){delete m_pSingleton;};
    
    public:
        static Singleton* Instance();
    
    private:
        static Singleton*m_pSingleton;
    };
    
    Singleton* Singleton::m_pSingleton = NULL;
    Singleton* Singleton::Instance()
    {
        if (!m_pSingleton)
        {
            m_pSingleton = new Singleton();
        }
    
        return m_pSingleton;
    }

      这是一个很棒的实现,简单易懂。但这是一个完美的实现吗?不!该方法是线程不安全的,考虑两个线程同时首次调用instance方法且同时检测到p是NULL值,则两个线程会同时构造一个实例给p,这是严重的错误!同时,这也不是单例的唯一实现!

    (2)懒汉单例模式

      a. 使用互斥对象实现懒汉模式

    // 单例模式
    class Singleton
    {
    private:
        Singleton(){};
        ~Singleton(){
            delete m_pSingleton;
            DeleteCriticalSection(&cs);}
    
    public:
        static Singleton * Instance();
    
    private:
        static Singleton *m_pSingleton;
        static CRITICAL_SECTION cs;
        static bool bInitCriticalSection;
    };
    
    CRITICAL_SECTION Singleton::cs = {0};
    bool Singleton::bInitCriticalSection = false;
    Singleton * Singleton::m_pSingleton = NULL;
    
    Singleton * Singleton::Instance()
    {
        if (!bInitCriticalSection)
        {
            InitializeCriticalSection(&cs);
            bInitCriticalSection = true;
        }
        if (!m_pSingleton)
        {
            EnterCriticalSection(&cs);
            m_pSingleton = new Singleton();
            LeaveCriticalSection(&cs);
        }
    
        return m_pSingleton;
    }

      b. 使用内部静态变量实现懒汉模式

       此方法也很容易实现,在instance函数里定义一个静态的实例,也可以保证拥有唯一实例,在返回时只需要返回其指针就可以了。推荐这种实现方法,真得非常简单

    // 单例模式
    class Singleton
    {
    private:
        Singleton(){}
        ~Singleton(){DeleteCriticalSection(&cs);}
    
    public:
        static Singleton * Instance();
    
    private:
        static CRITICAL_SECTION cs;
        static bool bInitCriticalSection;
    };
    
    CRITICAL_SECTION Singleton::cs = {0};
    bool Singleton::bInitCriticalSection = false;
    Singleton * Singleton::Instance()
    {
        if (!bInitCriticalSection)
        {
            InitializeCriticalSection(&cs);
            bInitCriticalSection = false;
        }
        EnterCriticalSection(&cs);
        static Singleton m_Singleton;
        LeaveCriticalSection(&cs);
    
        return &m_Singleton;
    }

    (3)饿汉单例模式

      饿汉实现本来就是线程安全的,不用加锁。为啥?自己想!

    // 单例模式
    class Singleton
    {
    private:
        Singleton(){};
        ~Singleton(){}
    
    public:
        static Singleton * Instance();
    
    private:
        static Singleton *m_pSingleton;
    };
    
    Singleton * Singleton::m_pSingleton = new Singleton();
    Singleton * Singleton::Instance()
    {
        return m_pSingleton;
    }
  • 相关阅读:
    Ex 6_20 最优二叉搜索树..._第六次作业
    Ex 6_12 凸多边形的最优三角剖分..._第六次作业
    Ex 6_9 某个字符串处理语言提供了一个将字符串一分为二的基本操作..._第六次作业
    Ex 6_4 判断序列是否由合法单词组成..._第六次作业
    maven配置阿里云镜像时(私服设置~JEECG)
    node、npm、webpack、vue-cli傻傻分不清?
    设计模式~观察者模式和发布订阅模式的比较:
    前端~定位属性position(relative、absolute、fixed)的分析
    debounce防抖函数减少函数调用的逻辑分析(包裹上时间的外衣,在时间还没来时,kill)
    js原生滚动与使用插件better-scroll不起作用原因
  • 原文地址:https://www.cnblogs.com/xiaobingqianrui/p/8807171.html
Copyright © 2011-2022 走看看