464 字
1 分钟
【CPP】设计模式
设计模式简述
针对 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设计要点
- 构造函数、拷贝构造、赋值私有化或 delete。
- 提供
getInstance()等静态访问接口。 - 多线程环境避免手写 DCLP,用 Meyers 或
std::call_once。 - 单例不是银弹:隐藏依赖、难测试,过度使用等同全局变量;优先考虑依赖注入。
单例 vs 全局变量
单例可延迟初始化、可禁止拷贝、可封装行为;但本质仍是全局状态,应克制使用。
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐
