C++中的单例模式

Posted 机械猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中的单例模式相关的知识,希望对你有一定的参考价值。

引言
在实现本地保存用户账密信息时遇到了静态实例化的问题,也就是单例模式,这里科普一下。在项目开发中,会遇到这样一种场景,一个类只能有一个对象被创建,如果有多个对象的话,可能会导致状态的混乱和不一致。这种情况下,单例模式是最恰当的解决办法。
单例模式是指程序只提供唯一一个类的实例,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例。具体使用场景如:
1、设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动;
2、数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取。

类加载顺序

讲述单例模式之前先看一下C++中类加载的顺序:
1、类还没被加载
先执行父类的静态代码块和静态变量初始化,静态代码块和静态变量的执行顺序跟代码中出现的顺序有关;
执行子类的静态代码块和静态变量初始化;
执行父类的实例变量初始化;
执行父类的构造函数;
执行子类的实例变量初始化;
执行子类的构造函数。
注意,加载类的过程是线程私有的,别的线程无法重入。
2、类已被加载
静态代码块和静态变量不会重复执行,后面再次创建该类实例时,只执行与实例相关的变量初始化和构造方法。


 实现方式

单例模式实现有饿汉模式、懒汉模式两种。
饿汉模式:在类被加载的时候就完成了实例化,属于线程安全的实现方式。
class singleton{protected: singleton(){};private: static singleton* m_instance;public: static singleton* initance();};singleton* singleton:: m_instance = new singleton;singleton* singleton::initance(){ return m_instance;}

饿汉模式是典型的异空间换取时间策略,在实例化m_instance变量时,直接调用类的构造函数,不管m_instance有没有被使用。
懒汉模式:当程序第一次访问单件模式实例时才进行创建。
#include <pthread.h>class Singleton{ private: static Singleton* m_instance; //指向唯一实例的静态私有指针  static pthread_mutex_t mutex; Singleton(){}; //构造函数为私有函数,因此外部无法创建该类的实例 Singleton(const Singleton&){}; //禁止拷贝 Singleton& operator=(const Singleton&){};//禁止赋值public: static Singleton* getInstance(); //外界唯一可以获取该实例的接口}static Singleton* getInstance() //静态函数只能在类外实现{ if (m_instance== nullptr) //只有在使用的时候才会实例化 { pthread_mutex_lock(&mutex); {      if (m_instance == nullptr) //两次判断是为了多线程安全     { Singleton*tmp = new Singleton(); //使用中间变量,确保构造函数运行完毕,初始化完成  m_instance= tmp;      } }  pthread_mutex_unlock(&mutex); } return m_instance; } Singleton pthread_mutex_tmutex = PTHREAD_MUTEX_INITIALIZER;Singleton* m_instance = nullptr;      
在Linux下还可以使用pthread_once()来确保进程中某个函数制备执行一次,感兴趣的可以用pthread_once实现单例模式。


以上是关于C++中的单例模式的主要内容,如果未能解决你的问题,请参考以下文章

C++中的单例模式

用 C++ 编写的单例模式中的一些错误

面经最频繁的单例模式一文彻底整明白

片段作为 Android 中的单例

C++的单例模式与线程安全单例模式(懒汉/饿汉)

C++ 安全单例模式总结