深圳幻海软件技术有限公司 欢迎您!

单例模式

2023-03-13

使用最广同时也是面试问的最多的一个设计模式代码:/**单例:即程序只能拥有一个实例,比如数据库连接池、日志系统等,这个类提供了一种访问其唯一的对象的方式。*单例分饿汉式和懒汉式,饿汉式无线程安全问题,懒汉式在多线程场景下存在线程安全问题,需要加锁实现线程同步。*/#include<mutex&

使用最广同时也是面试问的最多的一个设计模式

代码:

/** 单例:即程序只能拥有一个实例,比如数据库连接池、日志系统等,这个类提供了一种访问其唯一的对象的方式。
*   单例分饿汉式和懒汉式,饿汉式无线程安全问题,懒汉式在多线程场景下存在线程安全问题,需要加锁实现线程同步。
*/

#include <mutex>

class Singleton {
public:
    // static Singleton* getInstance() { 饿汉式
    //     return m_s;
    // }

    static Singleton* getInstance() {   //线程安全的懒汉式(双重判空➕互斥锁实现)
        if (nullptr == m_s) {
            m_mtx.lock();
            if (nullptr == m_s) {
                m_s = new Singleton();
            }
            m_mtx.unlock();
        }
        return m_s;
    }

private:
    Singleton();
    Singleton(const Singleton&);
    Singleton(const Singleton&&);
    Singleton& operator=(const Singleton&);
    Singleton& operator=(const Singleton&&);

    static Singleton* m_s;
    static std::mutex m_mtx;
};

Singleton* Singleton::m_s = nullptr;
std::mutex Singleton::m_mtx;

还有一种方式:静态局部变量实现的懒汉式,且线程安全的模式。

static SingleTon *get_instance() {
    static SingleTon s;
    return &s;
}

某天面试被问到单例模式有什么缺点,没了解过,只是说优点还是蛮多的。

查了一下,缺点:

1、由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。

2、单例类的职责过重,在一定程度上违背了“单一职责原则”。

3、滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。