In software engineering, double dispatch is a special form of multiple dispatch, and a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call.
In “double dispatch”, the operation executed depends on: the name of the request, and the type of TWO receivers (the type of the Visitor and the type of the element it visits). This essentially means different visitors can visit the same type and different types can be visited by the same visitor.
Double dispatch is a pattern you can use in C# to control how communication flows between two objects. A frequent use of the pattern is to pass "this" to a function on another class, allowing that class to communicate back to or manipulate the calling object instance.
This page shows how a dispatch table can be implemented in C or C++. A dispatch table is a way of associating a function with a string or numeric value in a general way. The concepts illustrated include data structure initialization, typedefs for functions, and calling functions through pointers.
I have a question on C++ double dispatch. In the code below, I want the results from the second set to match the results from the first set.
I don't know the actual type (unless I try dynamic_cast) but I do know that the object inherited from the BaseClass type. What is the most efficient (performance-wise) way to accomplish this?
After googling around for a while I found out about double dispatch and the loki multimethods. The problem I have with the Shape examples is that in my application, Processor and BaseClass are entirely independent and don't have a common method that they can call in each other. Secondly, there is only one Processor (i.e. nothing inherits from it).
Thanks for any help.
#include <iostream>
#include <string>
using namespace std;
class BaseClass{
public:
BaseClass(){}
virtual void myFunction(){cout << "base myFunction called" << endl;}
};
class Derived1: public BaseClass{
public:
Derived1():BaseClass(){}
void myFunction(){cout << "Derived1 myFunction called" << endl;}
};
class Derived2: public BaseClass{
public:
Derived2():BaseClass(){}
void myFunction(){cout << "Derived2 myFunction called" << endl;}
};
class Derived3: public BaseClass{
public:
Derived3():BaseClass(){}
void myFunction(){cout << "Derived3 myFunction called" << endl;}
};
class Processor{
public:
Processor(){}
virtual void processObj(BaseClass* bc){cout << "got a base object" << endl; bc->myFunction();}
virtual void processObj(Derived1* d1){cout << "got a derived1 object" << endl; d1->myFunction();}
virtual void processObj(Derived2* d2){cout << "got a derived2 object" << endl; d2->myFunction(); }
};
int main() {
BaseClass *bcp=new BaseClass();
Derived1 *dc1p=new Derived1();
Derived2 *dc2p=new Derived2();
Derived3 *dc3p=new Derived3();
Processor p;//can also use Processor* p = new Processor()
//first set results
p.processObj(bcp);
p.processObj(dc1p);
p.processObj(dc2p);
p.processObj(dc3p);
BaseClass *bcp1=bcp;
BaseClass *dc1p1=dc1p;
BaseClass *dc2p1=dc2p;
BaseClass *dc3p1=dc3p;
//second set results
p.processObj(bcp1);
p.processObj(dc1p1);
p.processObj(dc2p1);
p.processObj(dc3p1);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With