电话
400 9058 355
观察者模式核心是解决谁通知谁、何时解绑、生命周期管理三问题;需用std::weak_ptr避免野指针,通知时分离列表变更,参数按值或移动传递防悬空。
C++里实现观察者模式,关键不是“怎么写类”,而是解决「谁通知谁、何时解绑、生命周期怎么管」这三个问题。硬写一个 Observer 基类加虚函数,很容易在对象析构后还被调用,触发野指针崩溃。
detach()」这种易遗漏的方式 std::function + std::shared_ptr 组合比纯虚函数接口更灵活,也更容易和现代 C++ 工具链(如 QObject 信号槽、boost::signals2)对齐 std::weak_ptr 管理观察者生命周期裸指针或 std::shared_ptr 都会延长观察者寿命,造成循环引用或提前释放;std::weak_ptr 是唯一能“尝试访问、失败就跳过”的方案。
class Subject {
std::vector> observers_;
public:
void attach(std::shared_ptr obs) {
observers_.push_back(obs);
}
void notify() {
for (auto it = observers_.begin(); it != observers_.end();) {
if (auto obs = it->lock()) {
obs->onEvent();
++it;
} else {
it = observers_.erase(it); // 自动清理已销毁的观察者
}
}
}
};
lock() 返回 std::shared_ptr,空则说明观察者已析构 erase() 迭代器返回值,避免迭代器失效 std::vector::remov
e_if + lock(),因为 lock() 可能抛异常(虽然通常不会),且语义不如显式遍历清晰 通知时传参别用 const T& 引用——如果事件源对象在通知中途析构,引用就悬空了。尤其在多线程下,这个坑非常隐蔽。
int、std::string)直接按值传递 std::unique_ptr 或移动构造,避免拷贝开销 std::shared_ptr,确保只读且生命周期可控 例如:
void notify(std::string event_name, std::shared_ptrdata); // 而不是 void notify(const Data& data);
这是最常被忽略的并发与迭代陷阱。哪怕单线程,onEvent() 内部调用 subject.detach(this),也会导致当前 notify() 循环中迭代器失效。
weak_ptr,再统一清理 std::vector<:function>> 缓存回调,在 notify() 尾部执行 QMetaObject::invokeMethod(..., Qt::QueuedConnection) 就是这个思路的工程化实现 实际项目里,越早引入 std::weak_ptr 和「通知/变更分离」设计,后期越不容易掉进析构期 crash 的坑。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...