As shown in Program , the Visitor class interface also includes the member function IsDone. The IsDone member function is an accessor which is used to determine whether a visitor has finished its work. I.e., the IsDone member function returns the boolean value true if the visitor ``is done.''
The idea is this: Sometimes a visitor does not need to visit all the objects in a container. I.e., in some cases, the visitor may be finished its task after having visited only a some of the objects. The IsDone member function can be used by the container to terminate the Accept function like this:
void SomeContainer::Accept (Visitor& visitor) constfor each Object i in this container
if (visitor.IsDone ()) return; visitor.Visit (i);
To illustrate the usefulness of IsDone, consider a visitor which visits the objects in a container with the purpose of finding the first object that matches a given object. Having found the first matching object in the container, the visitor is done and does not need to visit any more contained objects.
The following code fragment defines a visitor which finds the first object in the container that matches a given object.
class MatchingVisitor : public Visitor { Object const& target; Object* found; public: MatchingVisitor (Object const& object) : target (object), found (0) {} void Visit (Object& object) { if (found == 0 && object == target) found = &object; } bool IsDone () { return found != 0; } };
The constructor of the MatchingVisitor visitor takes a reference to an Object instance that is the target of the search. I.e., we wish to find an object in a container that matches the target. For each object the MatchingVisitor visitor visits, it compares that object with the target and makes found point at that object if it matches. Clearly, the MatchingVisitor visitor is done when the found pointer is non-zero.
Suppose we have a container c that is an instance of a concrete container class, SomeContainer, which is derived from the abstract base class Container; and an object x that is an instance of a concrete object class, SomeObject, which is derived from the abstract base class Object. Then, we can call use the MatchingVisitor visitor as follows:
SomeContainer c; SomeObject x; MatchingVisitor v (x); c.Accept (v);
The observant reader will have noticed in Program that the Visit member function of the abstract Iterator class is pure virtual function whereas the IsDone function is not. It turns out that it is convenient to define a default implementation for the IsDone function that always returns false.