C++ 设计模式之单例模式

      设计模式 : 大佬们总结出的是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

      今天讲一讲,设计模式中创建型模式的单例模式(创建型模式还有工厂方法模式、抽象工厂模式、建造者模式、原型模式)

    单例模式:   通俗地说,一个类只能创建一个对象

           特点: 1.该模式下保证系统中该类只有一个实例,

               2. 提供一个全局访问点

               3. 该实例被所有程序共享

           C++实现:

            单线程模式下的单例模式    

class Singleton
{
  public:
      static Singleton* GetInstance()
      {
          if(m_instance==NULL)
          {
              m_instacne = new Singleton();
          }
          return m_instance;
      }  
  private: 
      Singleton(){}
      Singleton(Singleton const&) = delete;     
      Singleton& operator=(Singleton const&) = delete; 
      static Singleton* m_instance;
};

Singleton* Singleton::m_instance =NULL;

            那么他是怎么完成单例模式的条件呢?

           1. 私有构造,拷贝和赋值函数 ---  外界无法通过new创建对象

           2. 静态成员函数 ---  全局唯一访问点

           为什么是静态成员变量?   静态成员函数只能调用静态成员变量,并且静态成员变量必须在类外完成初始化。

           

           我们会发现,如果在多线程模式下,如果两个线程同时访问入口点,就会创建出两个!

           接下来介绍能保证线程安全的两种经典的单例模式:

           懒汉模式 --- 程序在需要的时候才创建实例 (人如其名,到了吃饭的时候才起床,是不是和你一样~)      

class Singleton
{
  public:
      static Singleton* GetInstance()
      {
          if(m_instance==NULL){
              Lock();
              if(m_instance==NULL)
              {
                  m_instacne = new Singleton();
              }
              return m_instance;
         }
      }  
  private: 
      Singleton(){}
      Singleton(Singleton const&) = delete;     
      Singleton& operator=(Singleton const&) = delete; 
      static Singleton* m_instance;
};
Singleton* Singleton::m_instance =NULL;

            我们发现,单例模式一般情况下用的都是懒汉模式,但是懒汉模式使用了加锁进行互斥操作

            那么为什么要判断两次?

            第一个判断  --- 提高效率,防止加锁影响效率

               第二个判断  --- 防止创建两个实例,如果两个线程同时访问,都到了加锁这里,那么当第一个线程释放锁的时候,第二个线程就会进去,不判断就会创建两个。

            应用场景: 对实例访问量小的项目 ---  时间换空间

             

            饿汉模式  ---  程序在开始就生成实例(还没睡醒,就饿得起床去吃饭了,大概昨天没吃晚饭吧~)        

class Singleton
{
public:
    static Singleton* GetInstance()
    {
        return singleton;
    }
private:
    Singleton() {}
    static Singleton *singleton;
};

Singleton* Singleton::GetInstance()
{
    return singleton;
}

Singleton* Singleton::singleton = new Singleton();

            如何保证线程安全?

            程序在进入主函数之前就由主线程以单线程的方式完成了

            应用场景:   对实例访问量大的项目 ---  空间换时间

          

posted @ 2019-10-31 11:10  Duikerdd  阅读(376)  评论(0编辑  收藏  举报