我至今是:使用了weak_ptr来实现观察者模式
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;
};
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。如何检查observers向量中的weak_ptr元素,以便我可以删除所需的Observer?
我也在寻找一些关于我的Un/Subscribe程序的参数类型的建议。使用std::shared_ptr<Observer>&
还是const std::shared_ptr<Observer>&
会更好?因为我们不会修改它?
我真的不想让Obserbles拥有他们的Observers,因为它似乎背叛了这个模式的意图,当然不是我想如何构建最终将使用模式的项目的其余部分。也就是说,我正在考虑的一个额外的安全/自动化层是让Observers存储weak_ptr的镜像向量。观察者在出路时可以取消订阅它订阅的所有观察对象,而观察者在其出路上可以消除观察对象的每个观察者对自身的反向引用。很显然,这两个班级在这种情况下会成为朋友。
请注意,'std :: remove_if'确实不**从容器中删除元素。你必须使用'container.erase'。搜索擦除 - 删除成语。 – Nawaz
...虽然在这种情况下,'std :: remove_if'会(可能)效率低下; 'std :: find_if'以及'.erase'会表现得更好(或者至少*语义*正确)。 – Nawaz
添加了wptr.expired()检查安全性并删除死亡的观察者。 – M2tM