oph*_*coe 7 c++ observers weak-ptr observer-pattern c++11
到目前为止我所拥有的是:
Observer.h
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;
};
Run Code Online (Sandbox Code Playgroud)
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
(de/constructors在这里实现但是空的,所以我把它们排除了)
我坚持的是如何实施Unsubscribe程序.我遇到了擦除 - 删除 - 结尾的习语,但我知道它不会像我设置我的Observable那样"开箱即用".如何检查观察者向量中的weak_ptr元素,以便我可以删除所需的Observer?
我也在寻找关于我的Un/Subscribe程序的参数类型应该是什么的一些建议.使用std::shared_ptr<Observer>&或更好const std::shared_ptr<Observer>&,因为我们不会修改它?
我真的不希望Observable拥有他们的Observers,因为它似乎背叛了模式的意图,当然不是我想要构建最终将利用该模式的项目的其余部分.也就是说,我正在考虑增加一层安全/自动化,让Observers存储一个weak_ptr的镜像向量.然后,一个出口观察者可以取消订阅它所订阅的所有Observable,并且一个Observable在其出路时可以从观察它的每个观察者中删除对它自己的反向引用.显然,在这种情况下,这两个班级将成为朋友.
您可以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()
);
}
Run Code Online (Sandbox Code Playgroud)
您确实应该传递observer为const std::shared_ptr<Observer>&.