Posle brisanja observer objekta (pomocu neke deleteObject funkcije koja se nalazi u ObjectManager objektu koji odrzava listu objekata), Subject jos uvek sadrzi pointer (koji vise nije validan) na obrisani observer objekat.
Malo sam istrazivao i uvideo da postoje 3 resenja za ovo ali nisam siguran koje je najbolje.
1. U destruktoru objekta koji se brise da se pozove funkcija koja obavestava Subject(e) tog objekta da je on pred brisanjem (subject->observerAboutToRemove(this)) i da se taj objekat izbaci iz liste svih subjecta koji ga sadrze kao observer.
2. Da se obrisani observeri izbrisu iz liste u Notify funkciji:
// .h
list<boost::weak_ptr<DObject> > m_observers;
// .cpp
void DObject::notify(int eventId, void *pData)
{
// brisemo sve expired weak_ptrs
m_observers.remove_if(bind(&boost::weak_ptr<DObject>::expired, _1));
foreach(boost::weak_ptr<DObject> wpObj, m_observers)
{
if(boost::shared_ptr<DObject> obj = wpObj.lock())
{
obj->onNotify(shared_from_this(), eventId, pData);
}
}
}
3. Koriscenje 'Delayed deallocation' http://www.boost.org/doc/libs/...s/smart_ptr/sp_techniques.html ali cu onda morati da m_observers cuvam kao listu shared_ptr. Kreirao bih globalnu listu _objectsForRemoving i onda bih brisao sve objekte izjednom u nekom pogodnom trenutku za to, npr. u main loop.
Meni se najvise dopada resenje 1. ali nisam siguran da li je dobro... Mozda se desi da u nekoj tacki i subject i observer budu nevalidni ili mozda jos neki bug...
Resenje 2. je ok ali mi nije elegantno.
Resenje 3. je mozda idealno, samo da se vidi u kom trenutku je najpogodnije prazniti listu obrisanih observera.
Da li imate neka iskustva sa ovim interesantnim problemom i mozda neki savet kako je najbolje napraviti ovaj sistem?