到目前为止,我有:
观察者
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/