I have an object that has a list of 'observers'. These observers get notified of things, and they might respond to this change by adding or removing themselves or other observers from the object.
I want a robust, and not unnecessarily slow, way to support this.
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?
}
}
I could perhaps have a flag, set by add_ and remove_, to reset my iterator if it gets invalidated, and then perhaps a 'generation' counter in each observer so I know if I've already called it?