#include #include #include #include #include #include template struct Observer { virtual ~Observer() = default; virtual void update(State state) = 0; }; class Browser { public: enum class State { Closing, FocusChanged }; using BrowserObserver = Observer; ~Browser() { std::cout << "Browser is closing\n"; notify(State::Closing); std::cout << "Browser closed\n"; } // Rule of 5 :) void attach(BrowserObserver* observer) { _observers.push_back(observer); } void detach(BrowserObserver* observer) { std::erase(_observers, observer); } private: void notify(State state) const { std::ranges::for_each(_observers, [state](auto* observer) { observer->update(state); }); } std::vector _observers; }; class TabStripManager : public Browser::BrowserObserver { public: TabStripManager(Browser* browser) : _browser(browser) { assert(browser); browser->attach(this); } ~TabStripManager() { if (_browser) { _browser->detach(this); } } // Rule of 5 :) // dispatch message void update(Browser::State state) override { switch (state) { case Browser::State::Closing: { browserAboutToQuit(); return; } case Browser::State::FocusChanged: { browserFocusChanged(); return; } } } private: void browserAboutToQuit() { std::cout << "TabStripManager will close tabs\n"; _browser = nullptr; } void browserFocusChanged() { std::cout << "TabStripManager lost focus\n"; } Browser* _browser; }; int main() { std::unique_ptr browser = std::make_unique(); TabStripManager manager(browser.get()); browser = nullptr; }