1. 单例模式的核心概念与应用场景
单例模式(Singleton Pattern)是23种经典设计模式中最简单却最容易用错的一种。它确保一个类只有一个实例,并提供一个全局访问点。在C++中实现单例看似简单,但要做到线程安全、内存安全却需要深入理解语言特性。
1.1 为什么需要单例
想象你正在开发一个日志系统。如果每个需要记录日志的模块都自己创建Logger实例,不仅会造成资源浪费,更会导致日志文件被多个实例争抢写入。这时就需要单例模式来保证全局唯一的日志器。
典型的应用场景包括:
- 配置管理(全局配置唯一性)
- 设备驱动(如打印机假脱机)
- 线程池/连接池管理
- 缓存系统
- 状态管理类
注意:单例常被滥用,在不需要严格唯一性的场景使用单例会破坏代码的可测试性。比如用单例管理业务数据就是典型的反模式。
1.2 单例与全局变量的本质区别
虽然单例提供全局访问,但与全局变量有本质不同:
cpp复制// 全局变量方式
Logger globalLogger; // 构造时机不可控
// 单例方式
Logger& getLogger() { // 按需构造
static Logger instance;
return instance;
}
关键差异在于:
- 延迟初始化能力(首次访问时才创建)
- 派生支持(可通过基类接口返回不同子类)
- 更可控的生命周期
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础单例实现与线程安全问题
2.1 经典DCLP实现及其缺陷
双重检查锁定模式(DCLP)曾是经典实现:
cpp复制class Singleton {
public:
static Singleton* getInstance() {
if (!instance_) { // 第一次检查
std::lock_guard<std::mutex> lock(mutex_);
if (!instance_) { // 第二次检查
instance_ = new Singleton();
}
}
return
