一、单例模式介绍
单例模式是一种常见的设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这个模式通常用于需要限制系统中某个类的实例数量的情况,例如数据库连接池、线程池、缓存等。使用单例模式可以避免在系统中创建多个实例,从而节省系统资源和提高性能。
在单例模式中,通常会将类的构造函数设为私有,这样外部就无法通过直接实例化该类来创建新的实例。而是通过一个静态方法或属性来获取该类的唯一实例。如果该类的实例不存在,则该方法或属性会创建一个新的实例并返回,否则直接返回已有的实例。这种方式确保了该类只有一个实例,并且该实例可以被全局访问。
二、实现
2.1懒汉式
懒汉式是单例模式中的一种实现方式,它的特点是在第一次使用时才创建实例。下面是一种非线程安全的懒汉式单例模式的实现:
class CSingleton
{
public:
static CSingleton* GetInstance()
{
if (m_pInstance == nullptr) {
m_pInstance = new CSingleton();
}
return m_pInstance;
}
private:
CSingleton() {};
static CSingleton* m_pInstance;
};
未了使线程安全,可以给它加锁
class CSingleton
{
public:
static CSingleton* GetInstance()
{
if (m_pInstance == nullptr) { // 避免每次调用 GetInstance的方法都加锁
std::unique_lock<std::mutex> lock(m_Mutex); // 加锁
if (m_pInstance == nullptr) { // 避免多线程重复创建
m_pInstance = new CSingleton();
}
}
return m_pInstance;
}
static void DeleteInstance()
{
std::unique_lock<std::mutex> lock(m_Mutex); // 加锁
if (m_pInstance) {
delete m_pInstance;
m_pInstance = nullptr;
}
}
CSingleton(const CSingleton&) = delete;
CSingleton& operator=(const CSingleton&) = delete;
CSingleton(CSingleton&&) = delete;
CSingleton& operator=(CSingleton&&) = delete;
private:
// 将其构造和析构成为私有的, 禁止外部构造和析构
CSingleton() {};
~CSingleton() {};
private:
static CSingleton * m_pInstance;
static std::mutex m_Mutex;
};
2.2 饿汉式
饿汉式是单例模式中的一种实现方式,它的特点是在类加载时就创建实例。这种方式的优点是实现简单,线程安全,没有锁的开销,但是缺点是可能会浪费一定的内存空间,因为实例在类加载时就被创建了,即使后续没有使用也会占用一定的内存空间。
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance;
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(Singleton&&) = delete;
private:
Singleton() {
// 私有构造函数
}
~Singleton() {
// 私有析构函数
}
};
注:C++11起,Singleton 最佳实现是静态局部对象的方法,该方法是线程安全的。C++11标准保证:如果多个线程试图同时初始化同一静态局部对象,则初始化严格只发生一次,但是C98不保证
参考: