最常用设计模式-单例模式

    这里主要讨论设计模式中单例模式的实现模板。


简介

    有些时候,我们可能期望某个class在整个程序中只能被实例化一次(例如:帮助窗口类、工厂类)。单例模式的目标就是解决这个问题。通过巧妙的设计结构(禁止new,用static保存一个实例),能实现这种功能。虽然看起来极其简单,但考虑到代码健壮性(例如:线程安全),具备一定的技巧。下面是一个例子,

/* 单例模式例子 */
#include <mutex>
#include <iostream>

class Singleton{
  public:
    static Singleton* get_instance();

  private:
    static Singleton *instance_;
    static std::mutex mutex_;  //实例锁,用于线程安全
    Singleton(){} // 禁用构造函数
};

Singleton* Singleton::instance_ = nullptr;
std::mutex Singleton::mutex_;

Singleton* Singleton::get_instance(){
  // 双重nullptr检查。当实例已经创建后,外层检查可以避免实例获取过程中的锁操作
  if(nullptr==instance_){
    // 锁用于线程安全
    std::unique_lock<std::mutex> lock(mutex_);
    // 内层nullptr检查可以避免重复创建实例
    if(nullptr==instance_){
      instance_ = new Singleton();
    }
  }
  return instance_;
}

int main(){
  // 通过将构造函数设置为privete,禁止了用户创建实例
  //Singleton *p0 = new Singleton();
  Singleton *p1 = Singleton::get_instance();
  Singleton *p2 = Singleton::get_instance();

  if(p1==p2){
    std::cout<<"p1==p2"<<std::endl;
  }

  return 0;
}

    注意,nullptr是c++11的特性,它能区分不同类型的空指针(例如:flaot类型,int类型,char类型等)。


讨论

    单例模式和工厂模式常常共用。在有些时候,我们需要在多个地方使用factory类来创建product类,但又没有必要创建多个工厂。此时可以考虑对factory类进行单例模式改造。


Reference

    [1] 《大话设计模式》,程杰,第21章

posted on 2018-06-08 15:47  深蓝e  阅读(184)  评论(0编辑  收藏  举报

导航