到目前为止,我有:

观察者

class Observer
{
public:
    ~Observer();
    virtual void Notify() = 0;
protected:
    Observer();
};

class Observable
{
public:
    ~Observable();
    void Subscribe( std::shared_ptr<Observer> observer );
    void Unsubscribe( std::shared_ptr<Observer> observer );
    void Notify();
protected:
    Observable();
private:
    std::vector<std::weak_ptr<Observer>> observers;
};

Observer.cpp
void Observable::Subscribe( std::shared_ptr<Observer> observer )
{
    observers.push_back( observer );
}

void Observable::Unsubscribe( std::shared_ptr<Observer> observer )
{
    ???
}

void Observable::Notify()
{
    for ( auto wptr : observers )
    {
        if ( !wptr.expired() )
        {
            auto observer = wptr.lock();
            observer->Notify();
        }
    }
}

(de/构造函数在这里实现,但为空,因此我省略了它们)

我所坚持的是如何实现退订过程。我遇到了擦除-删除-结束语,但我了解到它对于设置Observable的方式是“开箱即用”的。如何检查观察者 vector 中的weak_ptr元素,以便可以删除所需的观察者?

我还在寻找有关Un/Subscribe过程的参数类型的建议。使用std::shared_ptr<Observer>&const std::shared_ptr<Observer>&会更好,因为我们不会对其进行修改?

我真的不想让Observables拥有自己的Observer,因为这似乎背叛了该模式的意图,并且当然不是我想要构建最终将使用该模式的项目其余部分的方式。就是说,我正在考虑的安全性/自动化的附加层是让观察者存储“weak_ptr”的镜像 vector 。然后,离开的观察者可以取消订阅其已订阅的所有Observable,而离开的观察者可以从每个观察者中删除对其自身的反向引用。显然,在这种情况下,这两个类(class)将成为 friend 。

最佳答案

您可以将 std::remove_if std::erase结合使用,如下所示:

void Observable::Unsubscribe( std::shared_ptr<Observer> observer )
{
    std::erase(
        std::remove_if(
            this->observers.begin(),
            this->observers.end(),
            [&](const std::weak_ptr<Observer>& wptr)
            {
                return wptr.expired() || wptr.lock() == observer;
            }
        ),
        this->observers.end()
    );
}

您确实应该将observer传递为const std::shared_ptr<Observer>&

关于c++ - 使用weak_ptr实现观察者模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39516416/

10-13 07:00