C++:单例模式
1.什么是单例单就是单个的意思例就是实例化。所谓单例模式指的就是程序运行期间在全局范围内有且只有一个类的实例化存在。它其实是一种设计思想和语言没有关系。只要按照这种设计思想哪种语言都可以实现自己的单例模式。单例模式用的最多的场景就是工具类节省资源全局调用。而为了保证只有一个实例存在在设计单例时候就要将类的构造函数私有化防止外部创建。同时将类的拷贝构造函数和赋值操作符删除防止复制和赋值。单例模式的实现方式有三种。C11之前主要通过饿汉式或懒汉式实现C11之后通过静态局部变量实现。静态局部变量这种方式既简洁又高效。2.饿汉式饿汉式是通过类的静态成员变量实现的。因为静态成员变量的初始化是在main函数加载前完成的所以它天然是线程安全的。代码举例如下头文件EagerSingleton.h//EagerSingleton.h #pragma once #include iostream using namespace std; class EagerSingleton { public: static EagerSingleton getInstance() { return instance; } void doSomething() { cout EagerSingleton 做事... endl; } private: // 私有构造函数 EagerSingleton() { cout EagerSingleton 构造函数 endl; } // 拷贝构造和赋值操作符删除防止复制 EagerSingleton(const EagerSingleton) delete; EagerSingleton operator(const EagerSingleton) delete; // 静态实例在类外定义程序启动时即初始化 static EagerSingleton instance; };源文件EagerSingleton.cpp#include EagerSingleton.h EagerSingleton EagerSingleton::instance;调用方式EagerSingleton s1 EagerSingleton::getInstance()3.懒汉式懒汉式又可分为两种一种是简单版本一种是双重检测锁版本。他俩唯一区别就是第一个不是线程安全第二个是线程安全的。简单版本代码举例头文件LazySingleton.h#pragma once #include iostream using namespace std; class LazySingleton { public: static LazySingleton* getInstance() { if (instance nullptr) { // 多线程下可能同时进入 instance new LazySingleton(); } return instance; } void doSomething() { cout LazySingleton 做事... endl; } private: // 私有构造函数 LazySingleton() { cout LazySingleton 构造函数 endl; } // 拷贝构造和赋值操作符删除防止复制 LazySingleton(const LazySingleton) delete; LazySingleton operator(const LazySingleton) delete; // 静态实例在类外定义程序启动时即初始化 static LazySingleton* instance; };源文件LazySingleton.cpp#include LazySingleton.h LazySingleton* LazySingleton::instance nullptr;双重检测锁版本代码举例头文件LazySingletonDCL.h#pragma once #include iostream #include mutex using namespace std; class LazySingletonDCL { public: static LazySingletonDCL* getInstance() { // 第一层判断避免每次加锁损耗性能 if (instance nullptr) { lock_guardmutex lock(mtx); // 第二层判断防止多线程等待锁后重复创建 if (instance nullptr) { instance new LazySingletonDCL(); } } return instance; } void doSomething() { cout LazySingletonDCL 做事... endl; } private: // 私有构造函数 LazySingletonDCL() { cout LazySingletonDCL 构造函数 endl; } // 拷贝构造和赋值操作符删除防止复制 LazySingletonDCL(const LazySingletonDCL) delete; LazySingletonDCL operator(const LazySingletonDCL) delete; // 静态实例在类外定义程序启动时即初始化 static LazySingletonDCL* instance; static mutex mtx; };源文件LazySingletonDCL.cpp#include LazySingletonDCL.h LazySingletonDCL* LazySingletonDCL::instance nullptr; mutex LazySingletonDCL::mtx;调用方式LazySingleton* s1 LazySingleton::getInstance();4.静态局部变量方式这种方式是C11后才能使用是目前单例的最优解。代码举例如下头文件SingletonMeyer.h#pragma once #include iostream using namespace std; class SingletonMeyer { public: static SingletonMeyer getInstance() { // 第一次调用才创建线程安全 static SingletonMeyer instance; return instance; } void doSomething() { cout SingletonMeyer 做事... endl; } private: // 私有构造函数 SingletonMeyer() { cout SingletonMeyer 构造函数 endl; } // 拷贝构造和赋值操作符删除防止复制 SingletonMeyer(const SingletonMeyer) delete; SingletonMeyer operator(const SingletonMeyer) delete; };源文件SingletonMeyer.cpp#include SingletonMeyer.h //相关函数也可以在头文件中声明在这里实现。调用方式SingletonMeyer ins SingletonMeyer::getInstance(); ins.doSomething();