C++ 单例模式
单例模式(Singleton Pattern)
一、核心定义
单例模式是创建型设计模式 ,确保一个类有且只有一个实例,并提供一个全局访问点获取该实例。
二、核心特点
- 一个类只能创建唯一对象
- 自行创建实例
- 向整个系统提供这个实例
- 无参构造函数私有化
- 禁止拷贝、禁止赋值
三、使用场景
- 日志管理器
- 配置文件读取
- 数据库连接池
- 线程池、缓存、打印机池
- 全局唯一的工具类
四、C++ 单例模式 5 种标准实现(可直接编译)
实现 1:饿汉式(最简单、线程安全)
程序启动时就创建实例,天生线程安全,无多线程问题。
cpp
#include <iostream>
using namespace std;
class Singleton
{
public:
// 全局访问点
static Singleton& getInstance()
{
return instance;
}
void show()
{
cout << "饿汉式单例" << endl;
}
// 禁止拷贝、禁止赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
// 构造私有
Singleton() {}
// 程序启动就初始化
static Singleton instance;
};
// 静态变量初始化
Singleton Singleton::instance;
int main()
{
Singleton& s1 = Singleton::getInstance();
Singleton& s2 = Singleton::getInstance();
cout << &s1 << endl;
cout << &s2 << endl; // 地址相同
return 0;
}
优点 :简单、线程安全
缺点:不用也会创建,可能浪费资源
实现 2:懒汉式(基础版,非线程安全)
第一次使用时才创建实例。
cpp
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton* getInstance()
{
if (instance == nullptr)
{
instance = new Singleton();
}
return instance;
}
void show() { cout << "懒汉式单例" << endl; }
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() {}
static Singleton* instance;
};
Singleton* Singleton::instance = nullptr;
int main()
{
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
return 0;
}
注意 :多线程不安全,高并发会创建多个实例
实现 3:线程安全懒汉式(加锁)
C++11 线程安全版本
cpp
#include <iostream>
#include <mutex>
using namespace std;
mutex mtx;
class Singleton
{
public:
static Singleton* getInstance()
{
lock_guard<mutex> lock(mtx);
if (instance == nullptr)
{
instance = new Singleton();
}
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() {}
static Singleton* instance;
};
Singleton* Singleton::instance = nullptr;
实现 4:双检查锁 DCL(高性能线程安全)
企业最常用
cpp
#include <iostream>
#include <mutex>
using namespace std;
class Singleton
{
public:
static Singleton* getInstance()
{
if (instance == nullptr)
{
lock_guard<mutex> lock(mtx);
if (instance == nullptr)
{
instance = new Singleton();
}
}
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() {}
static Singleton* instance;
static mutex mtx;
};
Singleton* Singleton::instance = nullptr;
mutex Singleton::mtx;
实现 5:C++11 最优方案 Meyers 单例(推荐!)
最简单、线程安全、无内存泄漏
cpp
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
void show() { cout << "Meyers 单例(C++11最佳)" << endl; }
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() {}
};
int main()
{
Singleton& s1 = Singleton::getInstance();
Singleton& s2 = Singleton::getInstance();
s1.show();
return 0;
}
优点:
- 线程安全(C++11 保证静态变量初始化原子性)
- 懒加载
- 无内存泄漏
- 代码极简
五、单例模式自动释放(析构安全)
加入内部回收类,程序结束自动释放单例
cpp
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton* getInstance()
{
if (instance == nullptr)
{
instance = new Singleton();
}
return instance;
}
class AutoDelete
{
public:
~AutoDelete()
{
if (Singleton::instance)
{
delete Singleton::instance;
cout << "单例已自动释放" << endl;
}
}
};
private:
Singleton() {}
static Singleton* instance;
static AutoDelete ad;
};
Singleton* Singleton::instance = nullptr;
Singleton::AutoDelete Singleton::ad;
六、五种单例对比总结
| 实现方式 | 线程安全 | 性能 | 推荐指数 |
|---|---|---|---|
| 饿汉式 | 安全 | 高 | ⭐⭐⭐ |
| 基础懒汉式 | 不安全 | 高 | 不推荐 |
| 加锁懒汉式 | 安全 | 低 | ⭐⭐ |
| 双检查锁 DCL | 安全 | 高 | ⭐⭐⭐⭐ |
| Meyers 单例 | 安全 | 极高 | ⭐⭐⭐⭐⭐ |
七、C++ 单例必须遵守的 4 条规则
- 构造函数私有化
- 禁用拷贝构造
- 禁用赋值重载
- 提供全局唯一访问点
八、企业最佳实践
- 优先使用 Meyers 单例(C++11 最优)
- 禁止手动
new/delete,使用智能指针或自动释放 - 多线程环境必须使用线程安全版本
- 单例不建议存放大量数据,避免内存飙升