zoukankan      html  css  js  c++  java
  • 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();

                如何保证线程安全?

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

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

              

  • 相关阅读:
    sql 查询所有数据库、表名、表字段总结
    C# 随机数图片
    修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法
    ASP.NET 高级编程基础第八篇—Request对象和虚拟路径 转
    HTTP 状态码
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
    关于VS2010中无法进级EntityFramework的解决办法
    sql 存储过程 执行中 遇到的 问题 小结
    引用不到using System.Data.Entity.Database;(MVC3)
    如何通过ildasm/ilasm修改assem“.NET研究”bly的IL代码 狼人:
  • 原文地址:https://www.cnblogs.com/Duikerdd/p/11767401.html
Copyright © 2011-2022 走看看