#include class ButtonObserver { public: inline constexpr ButtonObserver () : next (nullptr) {} friend class Button; virtual bool onClick (int x) = 0; virtual int onDoubleClick (short x, long y) = 0; private: ButtonObserver* next; }; template class ButtonObserverRelay : public ButtonObserver { public: virtual bool onClick (int x) override { return static_cast (*this).onButtonClick (x, this); } virtual int onDoubleClick (short x, long y) override { return static_cast (*this).onButtonDoubleClick (x, y, this); } }; class Button { public: constexpr Button () : firstObserver (nullptr) {} void addObserver (ButtonObserver* obs) { obs->next = firstObserver; firstObserver = obs; } bool onClick (int x) { // Beispiel: Iteriere solange die Observer bis einer "true" zurück gibt for (ButtonObserver* o = firstObserver; o; o = o->next) { if (o->onClick (x)) return true; } return false; } int onDoubleClick (short x, long y) { // Beispiel: Summiere die Rückgabewerte der Observer int sum = 0; for (ButtonObserver* o = firstObserver; o; o = o->next) { sum += o->onDoubleClick (x, y); } return sum; } private: ButtonObserver* firstObserver; }; class Screen : public ButtonObserverRelay<0, Screen>, public ButtonObserverRelay<1, Screen> { public: Screen () { btn0.addObserver (static_cast*> (this)); btn1.addObserver (static_cast*> (this)); } bool onButtonClick (int x, ButtonObserverRelay<0, Screen>*) { std::cout << "Button 0 Click(" << x << ")" << std::endl; return true; } int onButtonDoubleClick (short x, long y, ButtonObserverRelay<0, Screen>*) { std::cout << "Button 0 DoubleClick(" << x << ", " << y << ")" << std::endl; return 0; } bool onButtonClick (int x, ButtonObserverRelay<1, Screen>*) { std::cout << "Button 1 Click(" << x << ")" << std::endl; return true; } int onButtonDoubleClick (short x, long y, ButtonObserverRelay<1, Screen>*) { std::cout << "Button 1 DoubleClick(" << x << ", " << y << ")" << std::endl; return 0; } Button btn0, btn1; }; int main () { Screen s; s.btn0.onClick (42); s.btn0.onDoubleClick (12, 3456); s.btn1.onClick (1); s.btn1.onDoubleClick (2, 3); }