观察者模式在C++中通过抽象接口、weak_ptr和智能指针实现松耦合:Subject用vector管理观察者,notify时lock()确保安全;Observer继承抽象类并实现update();生命周期由shared_ptr明确归属。

观察者模式在 C++ 中的核心是让被观察者(Subject)不依赖具体观察者(Observer),只依赖抽象接口;观察者也只需知道如何被通知,无需了解被观察者的内部实现。关键在于用抽象类 + 智能指针 + 容器管理生命周期,避免裸指针和内存泄漏。
定义抽象观察者接口
所有观察者必须实现统一的更新接口,通常命名为 update()。接口中可传入被观察者指针或事件数据,便于观察者获取上下文:
- 用纯虚函数强制子类实现,确保多态性
- 推荐传入 const Subject& 或 std::shared_ptr
,避免暴露实现细节 - 不建议在接口中暴露 notify()、attach() 等控制逻辑——那是被观察者的职责
实现被观察者基类(Subject)
Subject 管理观察者列表,并提供 attach/detach/notify 三个基本操作。重点是用 std::vector<:weak_ptr>> 存储观察者:
- weak_ptr 避免循环引用:Observer 持有 Subject 的 shared_ptr,Subject 若用 shared_ptr 存 Observer 就会锁死生命周期
- notify() 中遍历前先 lock(),跳过已销毁的观察者,安全且无崩溃风险
- attach() 接收 std::shared_ptr
,内部转为 weak_ptr 存储
具体观察者继承并实现响应逻辑
每个业务观察者(如 LogObserver、UIUpdater)继承 Observer 抽象类,重写 update()。里面只做本职工作:
立即学习“C++免费学习笔记(深入)”;
- 例如 LogObserver 在 update() 中把状态写进日志文件
- UIUpdater 调用 Qt 的 signal/slot 或直接刷新控件(注意线程安全)
- 不主动调用 Subject 的任何非 const 方法,保持单向依赖
使用时注意对象生命周期和线程安全
松耦合不等于无约束。实际使用需明确谁拥有谁:
- Subject 通常由上层模块(如 Application 或 Manager)持有 shared_ptr,长期存在
- Observer 生命周期较短(如窗口、临时处理器),创建时用 make_shared,离开作用域自动释放
- 若 notify 可能在多线程触发,Subject 的观察者容器需加 mutex(如 std::shared_mutex 用于读多写少场景)
不复杂但容易忽略。核心就三点:抽象接口隔离、weak_ptr 管理依赖、生命周期归属清晰。










