C++单例模式有饿汉式和懒汉式两种:饿汉式在程序启动时构造静态常量对象,线程安全但始终存在;懒汉式推荐C++11局部静态变量实现,首次调用时构造,线程安全且延迟初始化。

单例类确保一个类在整个程序中只有一个实例,并提供全局访问点。C++ 中常用懒汉(Lazy Initialization)和饿汉(Eager Initialization)两种实现方式,核心区别在于对象创建时机:懒汉式首次调用时才构造,饿汉式在程序启动时就构造。
饿汉模式:静态成员变量 + 静态函数
利用 C++ 全局对象在 main() 之前完成初始化的特性,直接定义一个静态 const 对象。线程安全(C++11 起保证),无需加锁,但对象始终存在,哪怕从未使用过。
示例:
class Singleton {
private:
Singleton() = default; // 私有构造
Singleton(const Singleton&) = delete; // 禁拷贝
Singleton& operator=(const Singleton&) = delete;
public:
static const Singleton& getInstance() {
return instance;
}
private:
static const Singleton instance; // 静态常量对象,程序加载时构造
};
// 类外定义并初始化
const Singleton Singleton::instance;
懒汉模式(线程安全版,C++11 及以后推荐)
延迟创建,首次调用 getInstance() 时才 new 出对象。C++11 标准规定:局部静态变量的初始化是线程安全的(由编译器自动加锁),因此无需手动同步,简洁又可靠。
立即学习“C++免费学习笔记(深入)”;
示例:
class Singleton {
private:
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
static Singleton& getInstance() {
static Singleton instance; // 第一次调用时构造,之后直接返回
return instance;
}
};
懒汉模式(传统双检锁,仅用于理解或旧标准环境)
在 C++11 之前,为避免每次加锁开销,常采用“双重检查锁定(Double-Checked Locking)”,但需注意内存重排序问题,必须配合 volatile(C++11 前)或原子操作(C++11+)才能真正安全。现代 C++ 已不推荐手写此版本。
关键点:
- 指针需声明为 static std::atomic
或 volatile Singleton*(旧标准) - 第一次判空后加锁,锁内再次判空,再创建
- new 操作需确保内存可见性(C++11 后 atomic_store + memory_order_release)
注意事项与建议
单例不是万能解法,过度使用会增加耦合、妨碍测试。若仍需使用,请注意:
- 析构顺序不可控:饿汉式对象在 main() 结束后销毁,懒汉式(堆分配)通常不自动析构,可考虑 atexit 注册清理函数
- 继承单例较复杂:一般不建议继承单例类;如需多态,改用工厂或依赖注入更合适
- 现代 C++ 优先选局部静态变量懒汉式 —— 简洁、线程安全、零成本抽象
- 避免在构造函数中调用其他单例(可能引发初始化顺序问题)










