''I [TomJones] have never understood how to properly solve the following problem.  I have a base class B and any number of derived classes (we'll call them Ds).  I now create methods to utilize these classes - to be generic I make all the methods accept B* parameters, that way I can always pass a D* where the signature calls for a B*.  Everything is going well thus far right?''

''Okay, now I hit the problem.  What happens when, inside one of the methods, I need to take a different code path based upon the *actual* type?  What I don't want to do is something like this:''

 >void Foo(B* b)
 >{
 >  switch (b->getTypeId())
 >  {
 >    case type_id_1:
 >      // cast b to the actual type and use it
 >    ...
 >  }
 >}

''I can't seem to figure out how to do something like this without resorting to switch/if statements.  I could use RunTimeTypeInformation (if using CeePlusPlus), but I still need special logic to determine which code path to take...''

You can use DynamicCast for this:

 void Foo(B* b) {
  if (D1 d1 = dynamic_cast<D1*>(b)) {
    /* do something with d1 */
  }
  else if (D2 d2 = dynamic_cast<D2*>(b)) {
    /* do something with d2 */
  }
 }

Now if you can extract the bodies of the if statements into functions like this:

 void Foo(B* b) {
  if (D1 d1 = dynamic_cast<D1*>(b)) {
    doSomething(d1);
  }
  else if (D2 d2 = dynamic_cast<D2*>(b)) {
    doSomething(d2)
  }
 }

Then you can put 'doSomething' into B as follows:

 class B {
  public:
    virtual void doSomething() = 0;
 };

...and implement it in D1 and D2 respectively.

If, however, the bodies of the if statements cannot be reduced to a single function signature:

 void Foo(B* b) {
  int x;
  int y;
  double z;
  /* some code */
  if (D1 d1 = dynamic_cast<D1*>(b)) {
    doSomething(d1, x, y);
  }
  else if (D2 d2 = dynamic_cast<D2*>(b)) {
    doSomething(d2, z)
  }
 }

.. Then you can use the visitor pattern:

 class B {
  public:
   virtual void accept(BVisitor* v) = 0;
 }

 class D1 : public B {
  public:
    virtual void accept(BVisitor* v) {
      v->visit(this);
    }
 }

 class D2 : public B {
  public:
    virtual void accept(BVisitor* v) {
      v->visit(this);
    }
 }

 class BVisitor {
  public:
    virtual void visit(D1*) = 0;
    virtual void visit(D2*) = 0;
 }

 class Do''''''Something''''''Visitor : public BVisitor {
  public:
    Do''''''Something''''''Visitor(int x, int y, double z)
    : itsX(x), itsY(y), itsZ(z)
    {}

    virtual void visit(D1* d1) {
      doSomething(d1, itsX, itsY);
    }

    virtual void visit(D2* d2) {
      doSomething(d2, itsZ);
    }

  private:
    int itsX;
    int itsY;
    double itsZ;
 }

 void Foo(B* b) {
  int x;
  int y;
  double z;
  /* some code */
  Do''''''Something''''''Visitor v(x, y, z);
  b.accept(v);
 }

Take a look at the paper named 'CrossCasting' in the resources section of http://www.objectmentor.com

Also check out the discussion of the Visitor pattern in the DesignPatternsBook, and also in "AgileSoftwareDevelopmentPrinciplesPatternsAndPractices: ( http://www.objectmentor.com/PPP )

-- UncleBob [''reprinted without permission'']
------
Graphically:

http://128.42.6.89/JavaResources/DesignPatterns/Visitor.jpg
-----
See also: DoubleDispatchExample