目录
概念
确保一个类只有一个实例,并提供一个全局访问点来访问该实例的创建模式。
实现三要素
①控制对象生成(确保只能单例类自己创建实例)
私有化构造、析构、拷贝、重载等号赋值函数
②私有静态成员变量(确保只有一个实例)
保存实例(如私有静态类指针)
③公有静态成员函数(提供调用方法)
生产并返回静态指针
分类
根据类的静态成员变量初始化的时机,可将单例分为:
①饿汉单例
初始化给内存,以空间换时间(安全)
②懒汉单例
其初始化为空,以时间换空间(不安全)
解决懒汉单例安全问题,可加双重检验锁
if (instance==nullptr) //外层判断,题所性能
{
unique_lock<mutex>ul(g_mutex); //唯一锁,防止异常导致死锁(自动上锁解锁)
//g_mutex.lock();
if (!instance) { //内存判断,提升安全
instance = new Singleton;
}
//g_mutex.unlock();
}
两种单例模式的实现
#include "stdafx.h"
#include <iostream>
#include <mutex>
using namespace std;
mutex g_mutex;
class Singleton {
private:
static Singleton * volatile instance; //volatile 异变的,防止编译器优化,不要从寄存器读,而从原始数据去读
static mutex m_mutex;
Singleton() {}
~Singleton() {}
Singleton(const Singleton&t) {}
void operator=(const Singleton&t) {}
public:
static Singleton* getInstance()
{
if (instance==nullptr) //外层判断,题所性能
{
unique_lock<mutex>ul(g_mutex); //唯一锁,防止异常导致死锁(自动上锁解锁)
//g_mutex.lock();
if (!instance) { //内存判断,提升安全
instance = new Singleton;
}
//g_mutex.unlock();
}
return instance;
}
void release() {
if (instance)
{
delete instance;
instance = nullptr;
cout << "释放成功" << endl;
}
else
{
cout << "已经释放了" << endl;
}
}
};
//Singleton* Singleton::instance = new Singleton; //饿汉单例
Singleton* volatile Singleton::instance = nullptr; //懒汉单例
mutex Singleton::m_mutex;
class SingletonTwo {
private:
SingletonTwo() {}
~SingletonTwo() {}
SingletonTwo(const SingletonTwo&t) {}
void operator=(const SingletonTwo&t) {}
public:
static SingletonTwo* getInstance() {
static SingletonTwo obj; //静态局部变量,只会初始化一次,再次进来不会再初始化,(类似懒汉模式
return &obj;
}
};
int main()
{
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
cout << s1 << " " << s2 << endl;
if (s1==s2)
{
cout << "ok" << endl;
}
else
{
cout << "no" << endl;
}
s1->release();
s2->release();
cout << endl;
SingletonTwo* a1 = SingletonTwo::getInstance();
SingletonTwo* a2 = SingletonTwo::getInstance();
if (a1 == a2)
{
cout << "ok" << endl;
}
else
{
cout << "no" << endl;
}
return 0;
}
使用场景
频繁实例化后又销毁时,以及实例化时耗费时间和资源
如数据库连接池、线程池、日志封装查询、缓存、资源共享和配置管理等。