I already trashed the example; with short 3 object array of objects
in same inheritance tree and pure abstract base visitor it is so
hopelessly far from both hint of various responsibilities that
visitors are capable of taking and difficulties that visitors may
need to solve and ways to solve those. It was so stupid that one
of most complex patterns could be easily confused with one of
most simple things.
Certainly there is difference. Iterator is over particular container.
It is very blunt and simple. Most iterators are just wrappers around
single pointer. The code is short since an iterator needs only to
know how to navigate in that container.
The visitors typically visit (part of) runtime object graph. A visitor
visiting object of type X that may point at objects of type Y
can go and visit those too. All that visitable classes have to contain
is one-liner "accept" member function; rest of the responsibilities
are upon the visitor. Once the classes are made visitable by base
visitor there are no changes needed in the code of classes for to
add yet another visitor that can visit with other goal. However the
visitors need to be familiar with all the classes visited.
The navigation may be far more trickier than business of iterator
since data of real applications is not always a simple tree. Several
of X may have pointer to same Y or Y may point to Z that may point
back to one of X. On such cases the visitors need to be smart and
to keep track of places been at to reduce the work and to avoid
hanging lost forever in that runtime data maze with such loops.
Therefore it is wise to keep that smartness of navigation in base
visitor. When data structure is changed then most related changes
will be in base visitor and actual visitors need to be changed only
if new types to visit are added.
One may say that they never have such loops and it is program
design error. So? We are not gods, we make typos. How to find
out that our program does not have such things run-time? Easiest
answer is "with visitor". ;-)