Buddha Buck wrote: ...
My solution was:
template <typename T> class wxObserver : public Observer { private: T* p; wxObserver(); public: wxObserver(T* p) : p(p); void update(shared_ptr<Observed> o) { if (p) p->update(o); } }
class MyWidget : public wxWidget { private: shared_ptr
observer; public: MyWidget(...) : wxWidget(...), observer(this) { ... observed->register(observer); ... } ... } The idea is that when a MyWidget is created, it creates a shared pointer to a wxObserver and can register that wxObserver with observed objects without a problem. When wxWidgets chooses to delete the MyWidget, the shared pointer the MyWidget goes away, the wxObserver is deleted, and the weak pointers held by the observed objects expire. The implementation of Observed::notifyObservers() checks to make sure that the observers still exist before update()ing them, and only the live observers are updated.
The problem is that sometimes, after wxWidgets destroys a MyWidget, calls to Observed::notifyObservers() crashes with a segfault within the call to i->lock().
I think I see one problem in your code, but it cannot explain a segfault within i->lock(). When MyWidget is destroyed, if at the exact same time an Observed locks its weak_ptr to the wxObserver, the T* p pointer will dangle. Can you post a stack trace? The problem you describe sounds like a race between notifyObservers and ~Observed or register, is that possible?