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

 更新时间:2016年12月16日 11:46:08   作者:jiayayao  
这篇文章主要为大家详细介绍了C++和java设计模式之单例模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。其构造过程由自身完成,可以将构造方法定义为private型的,这样外界就只能通过定义的静态的函数Instance()构造实例,这个函数的目的就是返回一个类的实例,在此方法中去做是否有实例化的判断。客户端不再考虑是否需要去实例化的问题,把这些都交给了单例类自身。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法,就是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。

C++版本:

  template <class T>
  class Singleton
  {
  public:
    static inline T* Instance();
    static inline void ReleaseInstance();

  private:
    Singleton(void){}
    ~Singleton(void){}
    Singleton(const Singleton&){}
    Singleton & operator= (const Singleton &){}

    static std::auto_ptr<T> m_instance;
    static ThreadSection m_critSection;
  };

  template <class T>
  std::auto_ptr<T> Singleton<T>::m_instance;

  template <class T> 
  ThreadSection Singleton<T>::m_critSection;

  template <class T>
  inline T* Singleton<T>::Instance()
  {
    AutoThreadSection aSection(&m_critSection);
    if( NULL == m_instance.get())
    {
      m_instance.reset ( new T);
    }

    return m_instance.get();
  }
  template<class T>
  inline void Singleton<T>::ReleaseInstance()
  {
    AutoThreadSection aSection(&m_critSection);
    m_instance.reset();
  }

#define DECLARE_SINGLETON_CLASS( type ) \
  friend class std::auto_ptr< type >;\
    friend class Singleton< type >;

   多线程时Instance()方法加锁保护,防止多线程同时进入创建多个实例。m_instance为auto_ptr指针类型,有get和reset方法。发现好多网上的程序没有对多线程进行处理,笔者觉得这样问题很大,因为如果不对多线程处理,那么多线程使用时就可能会生成多个实例,违背了单例模式存在的意义。加锁保护就意味着这段程序在绝大部分情况下,运行是没有问题的,这也就是笔者对自己写程序的要求,即如果提前预料到程序可能会因为某个地方没处理好而出问题,那么立即解决它;如果程序还是出问题了,那么一定是因为某个地方超出了我们的认知。

  再附一下Java版的单例模式:

public class Singleton {
  private Singleton() {    
  }
  
  private static Singleton single = null;
  
  public static Singleton getInstance() {
    if (single == null) {
      synchronized (Singleton.class) {
        if (single == null) {
          single = new Singleton();
        }        
      }
    }
    
    return single;
  }
}

   上述代码中,一是对多线程做了处理,二是采用了双重加锁机制。由于synchronized每次都会获取锁,如果没有最外层的if (single == null)的判断,那么每次getInstance都必须获取锁,这样会导致性能下降,有了此判断,当生成实例后,就不会再获取锁。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++ std::initializer_list 实现原理解析及遇到问题

    C++ std::initializer_list 实现原理解析及遇到问题

    这篇文章主要介绍了C++ std::initializer_list 实现原理勘误,本文通过源码解析给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • C语言中#pragma预处理指令的使用

    C语言中#pragma预处理指令的使用

    在所有的预处理指令中,#pragma指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作,本文主要介绍了C语言中#pragma预处理指令的使用,感兴趣的可以了解一下
    2023-12-12
  • C语言之关于二维数组在函数中的调用问题

    C语言之关于二维数组在函数中的调用问题

    这篇文章主要介绍了C语言之关于二维数组在函数中的调用问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C语言平衡二叉树详解

    C语言平衡二叉树详解

    这篇文章主要介绍了C语言平衡二叉树的相关资料,需要的朋友可以参考下,小编觉得这篇文章写的还不错,希望能够给你带来帮助
    2021-11-11
  • C语言每日练习之进制转换

    C语言每日练习之进制转换

    这篇文章主要介绍了C语言进制转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11
  • C++中的explicit关键字详解

    C++中的explicit关键字详解

    这篇文章主要介绍了C++中的explicit关键字详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-07-07
  • 详解c++ libuv工作队列

    详解c++ libuv工作队列

    这篇文章主要介绍了c++ libuv工作队列的相关资料,帮助大家更好的理解和使用libuv,感兴趣的朋友可以了解下
    2021-02-02
  • C语言调用SQLite数据库实现数据增删改查

    C语言调用SQLite数据库实现数据增删改查

    SQLite是一种轻量级的关系型数据库管理系统,是一个开源的、零配置的、服务器端的、自包含的、零管理的、事务性的SQL数据库引擎,本文主要介绍了如何调用SQLite数据库实现数据增删改查,需要的可以参考一下
    2023-08-08
  • C++中String类常见题目分享

    C++中String类常见题目分享

    这篇文章主要为大家详细介绍了一些C++中String类的常见题目,文中的示例代码讲解详细,对我们掌握C++有一定的帮助,感兴趣的小伙伴可以了解一下
    2023-06-06
  • 如何在C语言的宏中使用类型关键字

    如何在C语言的宏中使用类型关键字

    如何在C语言的宏中使用类型关键字呢?以下是实现方法。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10

最新评论