Listing 2: Test run of inverted visitor technique
////////// event.h #include <iostream.h> #include "widget.h" class Event { public: virtual void visit(Widget& w) { w.handleEvent(*this); } }; class EventA : public Event { public: void visit(Widget& w) { w.handleEvent(*this); } }; class EventB : public Event { public: void visit(Widget& w) { w.handleEvent(*this); } }; class EventC : public EventB { public: void visit(Widget& w) { w.handleEvent(*this); } }; ///////// widget.h #include <iostream.h> class Event; class EventA; class EventB; class EventC; class Widget { public: virtual void handleEvent(Event&) { cerr << "Widget, Event" << endl; } virtual void handleEvent(EventA&) { cerr << "Widget, EventA" << endl; } virtual void handleEvent(EventB&) { cerr << "Widget, EventB" << endl; } virtual void handleEvent(EventC& c) { cerr << "Widget, EventC" << endl; handleEvent((EventB&)c); } }; class WidgetA : public Widget { public: void handleEvent(EventA&) { cerr << "WidgetA, EventA" << endl; } void handleEvent(EventB&) { cerr << "WidgetA, EventB" << endl; } }; class WidgetB : public Widget { public: void handleEvent(EventB&) { cerr << "WidgetB, EventB" << endl; } void handleEvent(EventC&) { cerr << "WidgetB, EventC" << endl; } }; class WidgetC : public WidgetB { public: void handleEvent(EventB&) { cerr << "WidgetC, EventB" << endl; } // void handleEvent(EventC&) // { cerr << "WidgetC, EventC" << endl; } }; //////// main.c #include "event.h" void myVisitEngine(Widget& w, Event& e) { e.visit(w); } int main() { WidgetA wa; WidgetB wb; WidgetC wc; EventA ea; EventB eb; EventC ec; Widget *eh = &wa; cerr << "-------------" << endl; cerr << "-------------" << endl; eh->handleEvent(ea); wa.handleEvent(ea); cerr << "-------------" << endl; eh->handleEvent(eb); ((Widget&)wa).handleEvent(eb); cerr << "-------------" << endl; eh->handleEvent(ec); wa.handleEvent(ec); cerr << "-------------" << endl; cerr << "-------------" << endl; eh = &wb; eh->handleEvent(ea); ((Widget&)wb).handleEvent(ea); cerr << "-------------" << endl; eh->handleEvent(eb); wb.handleEvent(eb); cerr << "-------------" << endl; eh->handleEvent(ec); wb.handleEvent(ec); cerr << "-------------" << endl; cerr << "-------------" << endl; eh = &wc; eh->handleEvent(ea); ((Widget&)wc).handleEvent(ea); cerr << "-------------" << endl; eh->handleEvent(eb); wc.handleEvent(eb); cerr << "-------------" << endl; eh->handleEvent(ec); wc.handleEvent(ec); cerr << "-------------" << endl; cerr << "-------------" << endl; myVisitEngine(wa,ea); myVisitEngine(wa,eb); myVisitEngine(wa,ec); cerr << "-------------" << endl; myVisitEngine(wb,ea); myVisitEngine(wb,eb); myVisitEngine(wb,ec); cerr << "-------------" << endl; myVisitEngine(wc,ea); myVisitEngine(wc,eb); myVisitEngine(wc,ec); cerr << "-------------" << endl; cerr << "-------------" << endl; return 1; } //////// Output ------------- ------------- // Each Widget is asked to handle each different // event in turn WidgetA, EventA // <-- First through a base class pointer // to the Widget WidgetA, EventA // <-- Then through a direct reference ------------- WidgetA, EventB WidgetA, EventB ------------- Widget, EventC // <-- Here since WidgetA has no handler for // EventC (which derives from EventB), WidgetA, EventB // it falls through to the base class, which // then reroutes to the EventB handler WidgetA, EventB ------------- ------------- Widget, EventA // <-- Since WidgetB has no EventA handler, Widget, EventA // it falls back to base the class // implementation ------------- WidgetB, EventB WidgetB, EventB ------------- WidgetB, EventC WidgetB, EventC ------------- ------------- Widget, EventA // <-- WidgetC has no EventA handler either Widget, EventA ------------- WidgetC, EventB WidgetC, EventB ------------- WidgetB, EventC // <-- This is an example of the different WidgetC, EventB // behavior from using a base class pointer // and a direct reference, when the EventC // handler does not exist. ------------- ------------- // Now a generic visitation engine is simulated, // which asks the event to visit the widget WidgetA, EventA WidgetA, EventB Widget, EventC // <-- Same behavior as above for // WidgetA and EventC WidgetA, EventB ------------- Widget, EventA WidgetB, EventB WidgetB, EventC ------------- Widget, EventA WidgetC, EventB WidgetB, EventC // <-- A generic base class engine will generate // this behavior. ------------- ------------- /* End of File */