singleton

来源:互联网 发布:精通javascript pdf 编辑:程序博客网 时间:2024/06/17 15:13

Singleton模式

singleton模式是GOF23中模式中比较简单的一种,也是可以笔试手写不多的的模式之一。笔试中经常遇到

  • 动机:保证特殊类在系统中只存在一个实例,从而确保逻辑正确性和效率
  • 定义: 保证一个类仅有一个实例,并提供一个该实例的全局访问点
  • UML类图如下

uml类图

其实现的要点:
- 一般不要支持拷贝构造函数和clone接口;构造函数一般设为 private(有时候可为protected)
- 注意单线程,多线程的单锁或 双检查锁的正确实现

实现1 线程非安全版本

class Singleton{private:    Singleton();    Singleton(const Singleton& other);public:    static Singleton* getInstance();    static Singleton* m_instance;};Singleton* Singleton::m_instance=nullptr;//线程非安全版本,可能出错Singleton* Singleton::getInstance() {    if (m_instance == nullptr) {        m_instance = new Singleton();    }    return m_instance;}

多线程版本,加锁实现,注意加锁的位置

//线程安全版本,但锁的代价过高Singleton* Singleton::getInstance() {    Lock lock;    if (m_instance == nullptr) {// 可能两次获得if        // 若锁在这里,还是出错        m_instance = new Singleton();    }    return m_instance;}

采用双检查锁(面试使用)

//双检查锁(但由于内存读写reorder不安全,更具体需要进一步说)Singleton* Singleton::getInstance() {    if(m_instance==nullptr){        Lock lock;        // 为了提高读性能        if (m_instance == nullptr) {            m_instance = new Singleton();        }    }    return m_instance;}

C++11 可以采用final实现 (阻止它的派生类重写当前虚函数)

Singleton的懒汉模式与饿汉模式

  • 懒汉模式
    第一次初始化的时候才会初始化自己,代码同上。因为每次得要询问if和用到锁,所以如果遇到处理大量数据时,锁会成为整个性能的瓶颈。

  • 饿汉模式
    Singleton在程序一开始就将自己实例化,之后的GetInstance方法仅返回实例的指针即可,这样就解决了上述提到的if语句影响效率的问题。饿汉模式适用于Singleton在程序运行过程中一直被频繁调用,这样由于预先加载了实例,访问实例时没有if语句,效率更高。

// - 饿汉模式class Singleton{private:    Singleton();    Singleton(const Singleton& other);public:    static Singleton* getInstance(){      return m_instance;    };    static Singleton* m_instance;};Singleton* Singleton::m_instance= new  Singleton();  //在此直接实例化

另外,对于更加详细的可以查看这篇博客[岳阳-C++单例模式 Singleton的实现]https://www.tianmaying.com/tutorial/singleton

原创粉丝点击