一、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()被几十个文件调用,考虑用依赖注入替换