前言
得益于c++11之后,静态变量初始化的线程安全性。“Meyers Singleton” 在 C++11 之后最常用、最经典的实现写法。
1. 最小可用版(Meyers Singleton)
关键点说明
-
局部静态变量
static Singleton objC++11标准保证其初始化按需且仅一次,并且线程安全
-
拷贝 & 赋值删除防止用户复制得到多个实例。
-
析构仍会在
main()返回后自动调用如果担心“静态析构顺序”问题,可换成第 3 节的“泄漏式”写法。
2. 模板泛化版
当你需要多个不同类都想“变成单例”时,可把样板逻辑抽成模板:
3. “不析构”写法(工业界更常用)
若你的单例在程序退出阶段被别的静态对象再次访问,可以把实例放在堆上并 永不释放,由操作系统回收内存,彻底规避“静态析构顺序”风险:
绝大多数大型项目(Chrome、LLVM、Abseil 等)都采用这种“泄漏式单例”,因为它简单且可靠。
4. std::call_once 版(显式控制)
如果团队有“禁止局部静态对象”或“需要显式销毁”的编码规范,可用 std::call_once + unique_ptr:
5. 何时选哪一种?
小结
- C++11 已保证 单例初始化 的线程安全,经典写法就是“局部静态 + 删除拷贝”。
- 析构阶段 才是单例真正的坑:如果你不确定别的静态对象会不会在析构里再次用到它,就“让它泄漏”最保险。
- 以上几种写法皆为工业界常用模式,可根据团队规范与场景自由选择