What is the difference between Double Dispatch and the Visitor Pattern?
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
In short
they come from to different conceptualizations that, in some languages where double dispatch is not natively supported, lead to the visitor pattern as a way to concatenate two (or more) single dispatch in order to have a multi-dispatch surrogate.
In long
The idea of multiple dispatch is – essentially – allow a call like
void fn(virtual base_a*, virtual base_b*);(note: not as a class member: this is NOT C++! )that can be overridden as
so that, when calling
the call is redirected to the override that matches the actual runtime type of both
paandpb. (You can generalize this to whatever number of parameters)In language like C++, C#, Java, this mechanism does not exist and runtime type dispatching basically works with just one parameter (that, being just one, is made implicit in the function by making the function itself member of the class:
in other words, the pseudocode
becomes the (real C++)
Note that here there is no more
virtualin front ofbase_b, that from now is static.A call like
pa->fn(pb)if pa points to a derived_a2 and pb to a derived_b1 will be dispatched toderived_a2::fn(base_b*), no matter if there is a derived_a2::fn(derived_b1*) in there: the run-time type of the object pointed by pb is not taken into account.
The idea of the visitor patter is that you call the virtual dispatch of an object that calls (eventually back) the virtual dispatch of another:
now, a call like
pa->fn(pb), if pa points to derived_a1 and pb to derived_b1, will finally go toderived_a1::on_visit(derived_b1*).