 // Purpose.  Visitor (adding ops)       #include <iostream.h>
 //                                      class Visitor;
 // Discussion.  On the left, adding
 // new operations requires modifying    class Color { public:
 // all the current Color classes.  If      virtual void accept( Visitor& ) = 0;
 // we introduce an extra level of in-   };
 // direction (a Visitor hierarchy),
 // then operations capable of opera-    class Red : public Color { public:
 // ting on Color classes can be added      void accept( Visitor& );
 // without modifying any existing          void eye() { cout << "Red::eye\n"; }
 // code.  On the right, an entry point  };
 // for all future operations has been   class Blu : public Color { public:
 // added in the form of the accept()       void accept( Visitor& );
 // method.  Each of the previous op-       void sky() { cout << "Blu::sky\n"; }
 // erations has been encapsulated in    };
 // its own derived Visitor class.  Any
 // new operations simply require the    class Visitor { public:
 // addition of a new Visitor class.        virtual void visit( Red& ) = 0;
 //                                         virtual void visit( Blu& ) = 0;
 // When we call accept() on a Color     };
 // object, dynamic binding gets us to
 // the correct derived class of Color.  class CountV : public Visitor {
 // Then when we call visit() on the     public:
 // Visitor object, dynamic binding         CountV() { numRed_ = numBlu_ = 0; }
 // gets us to the correct derived          virtual void visit( Red& ) {
 // class of Visitor.  [Visitors and           numRed_++; }
 // Colors can be passed by address or      virtual void visit( Blu& ) {
 // passed by reference.]                      numBlu_++; }
                                            void reportNum() {
 #include <iostream.h>                         cout << "Reds " << numRed_ <<
                                               ", Blus " << numBlu_ << endl; }
 class Color {                           private:
 public:                                    int  numRed_, numBlu_;
    virtual void count() = 0;            };
    virtual void call()  = 0;
    static void reportNum() {            class CallV : public Visitor { public:
       cout << "Reds " << numRed_ <<        virtual void visit( Red& r ) {
       ", Blus " << numBlu_ <<endl; }          r.eye(); }
 protected:                                 virtual void visit( Blu& b ) {
    static int numRed_, numBlu_;               b.sky(); }
 };                                      };
 int Color::numRed_ = 0;
 int Color::numBlu_ = 0;                 void Red::accept( Visitor& v ) {
                                            v.visit( *this ); }
 class Red : public Color { public:      void Blu::accept( Visitor& v ) {
    void count() { numRed_++; }             v.visit( *this ); }
    void call() { eye(); }
    void eye() { cout << "Red::eye\n";}  void main( void )
 };                                      {
                                            Color* set[] = { new Red, new Blu,
 class Blu : public Color { public:            new Blu, new Red, new Red, 0 };
    void count() { numBlu_++; }             CountV  countOp;
    void call() { sky(); }                  CallV   callOp;
    void sky() { cout << "Blu::sky\n";}     for (int i=0; set[i]; i++) {
 };                                            set[i]->accept( countOp );
                                               set[i]->accept( callOp ); }
 void main( void )                           countOp.reportNum();
 {                                       }
    Color* set[] = { new Red, new Blu,
       new Blu, new Red, new Red, 0 };   // Red::eye
    for (int i=0; set[i]; i++) {         // Blu::sky
       set[i]->count();                  // Blu::sky
       set[i]->call(); }                 // Red::eye
     Color::reportNum();                 // Red::eye
 }                                       // Reds 3, Blus 2

