【发布时间】:2009-06-08 21:54:58
【问题描述】:
我有一个包含“观察者”列表的对象。这些观察者会收到有关事物的通知,并且他们可能会通过在对象中添加或删除自己或其他观察者来响应此更改。
我想要一种强大的,而不是不必要的缓慢的方式来支持这一点。
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_ 设置,如果它被无效,则重置我的迭代器,然后可能在每个观察者中设置一个“生成”计数器,以便我知道我是否已经调用它?
【问题讨论】:
-
请注意:您不止一次将“observer”拼错为“observer”。如果您在编译时没有注意到,这可能会导致一些令人头疼的问题。
-
一个 hacky 解决方法是使指针为 NULL,然后在所有地方进行 NULL 检查。这样你就不需要删除它了。
-
Lodle - 使用 [] 运算符而不是迭代器来处理添加,让它成为一个实际的答案,我很有可能会接受它! O(n) 甜