文档目录

一、C++11 后的正确写法

class Logger {
public:
    static Logger& instance() {
        static Logger inst;  // C++11 起:线程安全的延迟初始化
        return inst;
    }

    void log(const std::string& msg) { /* ... */ }

    // 防止拷贝和移动
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;

private:
    Logger() = default;  // 私有构造函数,禁止外部创建
    ~Logger() = default;
};

为什么 C++11 后是线程安全的?

  • C++11 规定:函数内的 static 变量初始化是线程安全的,编译器会在初始化前后插入屏障。
  • 等价于 call_once + once_flag 的效果。

二、什么时候真的需要单例?

应该用:

  • 日志系统(整个进程只需一个日志文件写入点)
  • 硬件资源(如串口、NPU 设备,物理上只有一份)
  • 配置管理器(从文件加载一次配置,全局共享)

不该用:

  • 只是为了"方便全局访问"——这是全局变量的代名词,导致隐式依赖、测试困难
  • 如果你发现 instance() 被几十个文件调用,考虑用依赖注入替换