「オブザーバー」のリストを持つオブジェクトがあります。これらのオブザーバーは物事を通知され、オブジェクトまたは他のオブザーバーをオブジェクトに追加または削除することによって、この変更に対応することができます。イテレータを無効にしないアイテムの追加と削除
私は強く、これをサポートするために不必要に遅くない方法を望んでいます。
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_によって設定されたフラグを、持っている、と可能性があり、各観測で、おそらく「世代」カウンタ私はすでにそれを呼ばれてきた場合、私は知っているので、 ?
ちょうど注記:「オブザーバー」のスペルは2度以上「obsever」です。コンパイル時に気付かないと頭が痛いことがあります。 –
ハッキーな修正は、ポインタをNULLにして、その場所全体にNULLチェックを行うことです。この方法では、削除する必要はありません。 – Lodle
Lodle - 追加を処理するために反復子ではなく[]演算子を使用して実際の回答をしてください。それを受け入れる良い機会があります! O(n)sweet – Will