单例模式保证一个类只有一个实例,并且提供了全局访问该实例的方法。在单例模式中,通常使用一个静态方法或者一个静态变量来保存实例。该实例被程序的所有模块共享。
具体过程:
1、定义一个单例类
2、私有化构造函数,防止外界直接创界单例类的对象
3、禁用拷贝构造,移动赋值等函数,可以私有化,也可以直接使用=delete
4、使用一个公有的静态方法获取该实例
5、确保在第一次调用之前该实例被构造
在写具体代码之前还需要知道单例模式的两种分类,饿汉和懒汉。所谓的饿和懒其实是创建实例的状态形容。
饿汉就是一点不顾一切的感觉,在类加载的时候就创建唯一的单例实例,不论该实例是否会被使用。这种方式是线程安全的。
#pragma once
#include <mutex>
//饿汉模式
class Singleton {
private:
//私有构造函数
Singleton() {}
//私有静态指针,指向唯一的实例
static Singleton* instance;
public:
//禁用拷贝构造和赋值构造函数。
Singleton(const Singleton&) = delete;
Singleton& operator = (const Singleton&) = delete;
//获取唯一实例的静态方法
static Singleton* getInstance()
{
return instance;
}
};
Singleton* Singleton::instance = nullptr; //初始化静态成员
Singleton* Singleton::instance = new Singleton();
而懒汉则是有一种能少创建就少创建的偷懒的感觉,即只要在第一次调用获取实例的方法时才会创建唯一实例,从而节省资源。这种方式是线程不安全的,需要去加锁。
//加锁的懒汉模式
class SingletonH
{
private:
singletonH() {};
static SingletonH* instance;
static std::mutex mutex;
public:
Singleton(const Singleton&) = delete;
Singleton& operator = (const Singleton&) = delete;
static Singleton* getInstance()
{
if(instance == nullptr)
{
std::lock_guard<std::mutex>lock(mutex); //加锁
instance = new SingletonH();
}
return instance;
}
};
SingletonH* SingletonH::instance = nullptr;
总结:饿汉单例适合在程序启动时资源充足,且需要立即使用单例的场景。懒汉单例适合资源敏感的场景,或者单例实例较大且不一定每次都需要实例化时使用。