观察者模式在C++中通过std::function+std::vector实现解耦,Subject维护回调列表并支持attach/detach/notify,可扩展为模板支持参数传递,结合weak_ptr避免悬挂指针,C++20后可选用Boost.Signals2等成熟库。

观察者模式在 C++ 中核心是解耦“被观察者(Subject)”和“观察者(Observer)”,让 Subject 在状态变化时自动通知所有注册的 Observer,而无需知道它们的具体类型。现代 C++ 推荐用 std::function + std::vector 实现轻量、灵活、无侵入的版本,避免传统虚函数继承带来的强耦合。
用 std::function 实现简洁版观察者模式
不依赖继承,Observer 可以是普通函数、lambda、成员函数对象,Subject 仅持有一组可调用对象。
- Subject 维护一个
std::vector<:function>></:function>存储回调 - 提供
attach()添加观察者(返回 token 用于后续 detach) - 提供
notify()遍历并调用所有已注册回调 - 为支持安全移除,可用
std::shared_ptr<:function>></:function>或索引 token(示例用后者)
示例代码:
#include <iostream>
#include <vector>
#include <functional>
#include <memory>
class Subject {
std::vector<std::function<void()>> observers_;
int next_id_ = 0;
public:
// 返回唯一 token,用于 detach
int attach(std::function<void()> obs) {
observers_.push_back(obs);
return next_id_++;
}
void detach(int id) {
if (id >= 0 && id < static_cast<int>(observers_.size())) {
observers_[id] = nullptr; // 标记为空,notify 时跳过
}
}
void notify() {
for (auto& obs : observers_) {
if (obs) obs();
}
}
};
// 使用示例
int main() {
Subject sub;
// lambda 观察者
auto id1 = sub.attach([]{ std::cout << "Observer A notified.\n"; });
// 普通函数
auto handler = []{ std::cout << "Observer B triggered.\n"; };
auto id2 = sub.attach(handler);
sub.notify(); // 输出两行
sub.detach(id1); // 移除第一个
sub.notify(); // 只输出 Observer B
return 0;
}
登录后复制
支持参数传递与类型安全的进阶版
实际项目中常需通知时携带数据(如新值、事件类型)。可泛化为模板类,用 std::function<void t></void> 支持任意通知类型。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~