• 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();

                如何保证线程安全?

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

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

              

  • 相关阅读:
    【转帖】C#索引器
    .NET Framework升级的挑战
    【我翻译的文章】CodeSmith发布代替和扩展LINQ to SQL的工具——PLINQO
    升级到VS2008后的一些疑惑
    【我翻译的文章】你还需要数据层吗?
    Db4Objects发布Db4o 7.0,支持透明激活
    迎接游戏开发新世界——Zune Game和Micro Game
    20071223成都俱乐部活动
    db4o发布7.2,出现.NET 3.5版本,支持LINQ
    微软推出SCE SDK及其示例MSDN Reader
  • 原文地址:https://www.cnblogs.com/Duikerdd/p/11767401.html
Copyright © 2020-2023  润新知