我有一个包含'observers'列表的对象。这些观察者会收到有关事情的通知,他们可能会通过向对象添加或删除自己或其他观察者来响应此更改。在不使迭代器无效的情况下添加和删除项目
我想要一个强大的,而不是不必要的缓慢的方式来支持这一点。
class Thing {
public:
class Observer {
public:
virtual void on_change(Thing* thing) = 0;
};
void add_observer(Observer* observer);
void remove_observer(Observer* observer);
void notify_observers();
private:
typedef std::vector<Observer*> Observers;
Observers observers;
};
void Thing::notify_observers() {
/* going backwards through a vector allows the current item to be removed in
the callback, but it can't cope with not-yet-called observers being removed */
for(int i=observers.size()-1; i>=0; i--)
observers[i]->on_change(this);
// OR is there another way using something more iterator-like?
for(Observers::iterator i=...;...;...) {
(*i)->on_change(this); //<-- what if the Observer implementation calls add_ or remove_ during its execution?
}
}
我也许可以有一个标志,通过add_和remove_设置,重置我的迭代器,如果它得到无效,然后在每一个观察者或许是“一代”计数器,所以我知道如果我已经把它称为?
只是说明:您多次拼写“观察者”为“obsever”。如果您在编译时没有注意到这可能会导致一些头部划伤。 – 2009-06-08 21:59:08
一个hacky修复将是使指针为NULL,然后在整个地方做NULL检查。这样你不需要删除它。 – Lodle 2009-06-09 08:10:51
Lodle - 使用[]运算符而不是迭代器来处理添加,这是一个实际的答案,并且我很有可能接受它! O(n)sweet – Will 2009-06-09 17:50:16