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 */