首页 > 解决方案 > 在构造函数中注册weak_ptr观察者

问题描述

我正在尝试重写我们的 Observer / Observable 实现以使用 std::shared_ptr/std::weak_ptr 来摆脱代码中当前存在的一些讨厌的竞争条件。

通常,观察者会在满足某些条件或构造子对象时注册自己,如下所示:

// Used to be raw 'this' now child instead derives a weak_ptr and stores it
child->addObserver(shared_from_this()) 

并像这样在析构函数中注销自己:

child->removeObserver(this); // Not shared_from_this() since in destructor

在某些情况下,这可以正常工作,但是在许多情况下,观察者希望在构造函数中注册自己。由于尚未创建 shared_ptr,我们无法调用 shared_from_this()。

由于通常建议使用 weak_ptr 在 C++ 中实现观察者模式,我想知道解决上述问题的惯用方法是什么。

一些想法:

标签: c++multithreadinglistenershared-ptrobserver-pattern

解决方案


处理您所要求的问题的一种方法是创建一个由 a 持有shared_ptr并包含在“父级”中的显式观察者对象实例。观察者对象会将观察结果发送给父对象。

然而,由于孩子正在shared_ptr向 a注册 a weak_ptr,实际上父母不需要明确地将自己作为观察者移除。当孩子向观察者发送通知时,它首先检查是否weak_ptr有效。如果不再有效,可以原地移除观察者而不是通知。

void notify_observers (Event e) const {
    auto o = observers_.begin();
    auto erase = [this](decltype(o) o) {
        return observers_.erase(o);
    };
    while (o != observers_.end()) {
        if (auto l = o->lock()) ++o, l->notify(e);
        else o = locked_call(erase, o);
    }
}

在线尝试!


推荐阅读