单例模式是指在整个系统的生命周期里,保证一个类只能产生一个实例,确保该类的 唯一性
单例模式可以分为 懒汉式 和 饿汉式 ,两者之间的区别在于 创建实例的时间不同:
总结:将该类的构造,析构,拷贝构造和赋值构造全部声明为private,提供一个获取静态实例的方法
为什么要使用单例模式首先得解释什么是线程安全
在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外的情况
#include
#include
#include
// 线程不安全
// 懒汉式单例模式
class SingleInstance {
public:
// 获取静态单例对象
static SingleInstance* getInstance();
// 释放单例对象资源
static void deleteInstance();
// 其他功能函数....
private:
// 将其构造和析构函数声明为私有的,禁止外部构造和析构
SingleInstance();
~SingleInstance();
// 将其拷贝构造和赋值构造声明为私有的,禁止外部拷贝和赋值
SingleInstance(const SingleInstance& single);
const SingleInstance &operator = (const SingleInstance& single);
private:
// 唯一的静态单例对象指针
static SingleInstance* m_SingleInstance;
};
#include "SingleInstance.h"
//初始化静态成员变量
SingleInstance* SingleInstance::m_SingleInstance = NULL;
SingleInstance* SingleInstance::getInstance() {
if(m_SingleInstance == NULL) {
// 没有加锁是不安全的,当出现线程并发的时候可能会创建多个实例,不符合单例模式要求
m_SingleInstance = new (std::nothrow) SingleInstance;
}
return m_SingleInstance;
}
void SingleInstance::deleteInstance() {
// 若单例对象存在,则释放此资源
if(m_SingleInstance) {
delete m_SingleInstance;
m_SingleInstance = NULL;
}
}
SingleInstance::SingleInstance() {
}
SingleInstance::~SingleInstance() {
}
#include
#include
#include
// 线程安全
// 懒汉式单例模式
class SingleInstance {
public:
// 获取静态单例对象
static SingleInstance* & getInstance();
// 释放单例对象资源
static void deleteInstance();
// 其他功能函数....
private:
// 将其构造和析构函数声明为私有的,禁止外部构造和析构
SingleInstance();
~SingleInstance();
// 将其拷贝构造和赋值构造声明为私有的,禁止外部拷贝和赋值
SingleInstance(const SingleInstance& single);
const SingleInstance &operator = (const SingleInstance& single);
private:
// 唯一的静态单例对象指针
static SingleInstance* m_SingleInstance;
static std::mutex m_Mutex;
};
#include "SingleInstance.h"
//初始化静态成员变量
SingleInstance* SingleInstance::m_SingleInstance = NULL;
std::mutex SingleInstance::m_Mutex;
SingleInstance* & SingleInstance::getInstance() {
// 这里使用了两个 if判断语句的技术称为双检锁;好处是,只有判断指针为空的时候才加锁
// 避免每次调用 GetInstance的方法都加锁,锁的开销毕竟还是有点大的
if(m_SingleInstance == NULL) {
std::unique_lock lock(m_Mutex); // 加锁
if(m_SingleInstance == NULL) {
m_SingleInstance = new (std::nothrow) SingleInstance;
}
}
return m_SingleInstance;
}
void SingleInstance::deleteInstance() {
std::unique_lock lock(m_Mutex); // 加锁
if(m_SingleInstance) {
delete m_SingleInstance;
m_SingleInstance = NULL;
}
}
SingleInstance::SingleInstance() {
}
SingleInstance::~SingleInstance() {
}
// 线程安全
// 内置静态变量懒汉式单例模式
class SingleInstance {
public:
// 获取静态单例对象
static SingleInstance & getInstance();
// 其他功能函数....
private:
// 将其构造和析构函数声明为私有的,禁止外部构造和析构
SingleInstance();
~SingleInstance();
// 将其拷贝构造和赋值构造声明为私有的,禁止外部拷贝和赋值
SingleInstance(const SingleInstance& single);
const SingleInstance &operator = (const SingleInstance& single);
};
#include "SingleInstance.h"
SingleInstance & SingleInstance::getInstance() {
// 局部静态特性的方式实现单实例
static SingleInstance signal;
return signal;
}
SingleInstance::SingleInstance() {
}
SingleInstance::~SingleInstance() {
}
class SingleInstance {
public:
// 获取单实例
static SingleInstance* getInstance();
// 释放单实例
static void deleteInstance();
// 其他功能函数....
private:
// 将其构造和析构函数声明为私有的,禁止外部构造和析构
SingleInstance();
~SingleInstance();
// 将其拷贝构造和赋值构造声明为私有的,禁止外部拷贝和赋值
SingleInstance(const SingleInstance& single);
const SingleInstance &operator = (const SingleInstance& single);
private:
// 唯一的静态单例对象指针
static SingleInstance* m_SingleInstance;
};
#include "SingleInstance.h"
SingleInstance* SingleInstance::m_SingleInstance = new (std::nothrow) SingleInstance;
SingleInstance* SingleInstance::getInstance() {
return m_SingleInstance;
}
SingleInstance::SingleInstance() {
}
SingleInstance::~SingleInstance() {
}
单例模式的应用场景很多,例如:替换任意的全局变量;配置文件;设备管理器;数据池等
我们可以通过模板的形式,写出一个单例模式的模板类以友元的形式加入其他类中,方便之后其他类的套用
// 单例模板
template
class Singleton {
// 获取静态单例对象
static T* getInstance();
private:
// 将其构造和析构函数声明为私有的,禁止外部构造和析构
Singleton() {}
~Singleton() {}
// 将其拷贝构造和赋值构造声明为私有的,禁止外部拷贝和赋值
Singleton(const Singleton&);
const Singleton &operator = (const Singleton &);
private:
static T* m_instance;
};
template
T* Singleton::m_instance = new (std::nothrow) Singleton;
#include "Singleton.h"
class Single {
friend class Singleton;
public:
// 其他功能函数...
private:
// 将其构造和析构函数声明为私有的,禁止外部构造和析构
Single() {}
~Single() {}
// 将其拷贝构造和赋值构造声明为私有的,禁止外部拷贝和赋值
Single(const Single&);
const Single &operator = (const Single &);
private:
// 类自身数据成员
};