我有一個包含'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