2

I have a tree containing various subtypes of the my base node class. I now want to traverse this tree and do something with the nodes depending on their type.

The most straightforward idea is to just define a method doSomething in my base node class, but this means that to add functionality I have to add a method to all existing node subtypes.

The first thing that comes to mind to solve this is the Visitor pattern. However, I want to be able to create new subtypes without having to change all existing visitors - I want the new subtypes to inherit the way they are handled from their base type.

I think using dynamic_cast should do the trick, but I understood that it is a costly operation, and it will be called a lot, so that is not a good solution. And many people say it is a sign of bad design, although I do not see the problem in this case.

At this moment I am using the first solution as I see foresee much more added types than functionality, but is there a better way to do this?

  • Visitor allows you to add new functionalities easily as subtypes of Visitor, but doesn't really tolerate new subtypes of Node. Can you give concrete examples of what you want to do? It's hard to give good answers when the question is generalized. – Fuhrmanator Jun 19 '15 at 0:40
  • There is the Acyclic Visitor pattern described by R. Martin, but it has dynamic_cast, too: objectmentor.com/resources/articles/visitor.pdf – Fuhrmanator Jun 19 '15 at 0:43
  • @Fuhrmanator according Doc Brown new subtypes can easily be added, so why do you claim otherwise? Or do you mean when a new subtype requires a different behaviour from its base class? – Oebele Jun 22 '15 at 18:01
  • Design patterns often allow easily extending code. For example, it's easy to add a new Visitor, and the Node classes don't require changes. However, Visitor doesn't tolerate easily changing the Node classes. If you add a new concrete type of Node, that will require a new visit method in all the Visitor classes. See en.wikipedia.org/?title=Visitor_pattern#Diagram as an example. If you add a new Door class to the CarElement hierarchy, you will need to have a visit(Door door) method that needs implementing in all of the visitors. – Fuhrmanator Jun 22 '15 at 19:13
  • If the behaviors of the subclasses are the same, it's somewhat exceptional. Why define subclasses that are the same as the base class? – Fuhrmanator Jun 22 '15 at 19:15
3

I want the new subtypes to inherit the way they are handled from their base type

The classic GOF visitor pattern behaves exactly like that. For example, look the Wikipedia CarElement example (it is a Java example, but the important part is similar in C++). Lets assume you add new Wheel types like SquareWheel, RoundWheel by inheriting them from Wheel. Then, visit(Wheel &wheel) will process SquareWheel as well as RoundWheel, as long as you do not define any methods visit(SquareWheel &wheel) or visit(RoundWheel &wheel).

  • In my recollection the methods were visitSquareWheel(SquareWheel& wheel) etc. So I wonder what went wrong in my memory there... thanks! – Oebele Jun 18 '15 at 21:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.