464 字
1 分钟
【CPP】设计模式
2026-03-23

设计模式简述#

针对 recurring 问题的可复用面向对象方案,通常包含:模式名、问题、解决方案、效果。

单例 (Singleton)#

意图:保证一个类在程序生命周期内只有一个实例,并提供全局访问点。

现代推荐:Meyers 单例(局部静态)#

class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // C++11 起:初始化线程安全
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
void doSomething() const;
private:
Singleton() = default;
~Singleton() = default;
};

优点

  • 懒加载(首次调用时构造)。
  • 自动析构(程序结束时按静态对象销毁顺序)。
  • 无需手动 delete
  • C++11 保证局部静态初始化线程安全

原笔记勘误:懒汉式 new 单例若从不 delete,会泄漏;Meyers 单例无此问题。

饿汉式(静态成员对象)#

class SingletonEager {
public:
static SingletonEager& getInstance() { return instance; }
SingletonEager(const SingletonEager&) = delete;
SingletonEager& operator=(const SingletonEager&) = delete;
private:
SingletonEager() = default;
static SingletonEager instance;
};
SingletonEager SingletonEager::instance; // 程序启动时构造(main 前或静态初始化阶段)
饿汉Meyers 懒汉指针懒汉 + 双重检查
初始化时机静态存储期开始首次 getInstance首次 getInstance
线程安全静态初始化保证C++11 局部静态保证mutex + DCL
内存自动释放自动释放常泄漏 unless 注册 atexit
析构顺序与其他静态对象顺序有关同左可控制性差

懒汉式(指针,仅作了解)#

class SingletonLazy {
public:
static SingletonLazy* getInstance() {
if (!instance) {
instance = new SingletonLazy();
}
return instance;
}
// delete 拷贝...
private:
static SingletonLazy* instance;
};

多线程下上述代码不安全,需双重检查锁定(DCLP);且 new 分配的内存在进程结束前通常不会释放。C++11 后应优先 Meyers 或:

static std::unique_ptr<Singleton> instance;
// 在 getInstance 内用 std::call_once + make_unique

设计要点#

  1. 构造函数、拷贝构造、赋值私有化或 delete
  2. 提供 getInstance() 等静态访问接口。
  3. 多线程环境避免手写 DCLP,用 Meyers 或 std::call_once
  4. 单例不是银弹:隐藏依赖、难测试,过度使用等同全局变量;优先考虑依赖注入。

单例 vs 全局变量#

单例可延迟初始化、可禁止拷贝、可封装行为;但本质仍是全局状态,应克制使用。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【CPP】设计模式
https://lysj.work/posts/studynotes/cpp/cpp设计模式/
作者
Sekiro
发布于
2026-03-23
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录