Thursday, 18 June 2015

Multiple dispatching in C++

Multiple dispatching in Cpp with examples

AS of we know that C++ performs only single dispatching.
That is, if you are performing an operation on more than one object whose type is unknown C++ can invoke the dynamic binding mechanism on only one of those types.

The solution for the above problem is multiple dispatching.

Remember that polymorphism can occur only via member function calls, so if you want double dispatching to occur, there must be two member function calls: the first to determine the first unknown type, and the second to determine the second unknown type.

With multiple dispatching, you must have a virtual call to determine each of the types.

 Here is a working example for multiple dispatching:

#include "stdafx.h"

#include <iostream>

#include <iostream>

#include <vector>

#include <algorithm>

#include <cstdlib>

#include <ctime>

using namespace std;

class Class1;

class Class2;

class Class3;

enum Outcome { enmVal1, enmVal2, enmVal3 };
ostream& operator<<(ostream& MyOutStream, const Outcome MyOutStream1)

{

switch (MyOutStream1)

{

default:

case enmVal1: return MyOutStream << "enmVal1";

case enmVal2: return MyOutStream << "enmVal2";

case enmVal3: return MyOutStream << "enmVal3";

}

}

class ClassItem

{

public:

virtual Outcome GetCompete (const ClassItem*) = 0;

virtual Outcome GetVal (const Class1*) const = 0;

virtual Outcome GetVal (const Class2*) const= 0;

virtual Outcome GetVal (const Class3*) const = 0;

virtual ostream& print (ostream& MyOutStream) const = 0;
virtual ~ClassItem() {}

friend ostream& operator<<(ostream& MyOutStream, const ClassItem* pcIterator)

{

return pcIterator->print (MyOutStream);

}

};

class Class1 : public ClassItem

{

public:

Outcome GetCompete(const ClassItem* pcIterator)

{

return pcIterator->GetVal(this);

}
Outcome GetVal(const Class1*) const

{

return enmVal3;

}

Outcome GetVal(const Class2*) const

{

return enmVal1;

}

Outcome GetVal(const Class3*) const

{

return enmVal2;

}

ostream& print(ostream& MyOutStream) const

{

return MyOutStream << "Class1 ";

}

};

class Class2 : public ClassItem

{

public:

Outcome GetCompete(const ClassItem* pcIterator)

{

return pcIterator->GetVal(this);

}

Outcome GetVal(const Class1*) const

{

return enmVal2;

}

Outcome GetVal (const Class2*) const

{

return enmVal3;

}

Outcome GetVal (const Class3*) const

{

return enmVal1;

}

ostream& print (ostream& MyOutStream) const

{

return MyOutStream << "Class2";

}

};

class Class3 : public ClassItem {

public:

Outcome GetCompete(const ClassItem* pcIterator)

{

return pcIterator->GetVal(this);

}

Outcome GetVal(const Class1*) const

{

return enmVal1;

}

Outcome GetVal(const Class2*) const {

return enmVal2;

}

Outcome GetVal(const Class3*) const {

return enmVal3;

}

ostream& print(ostream& MyOutStream) const {

return MyOutStream << "Class3 ";

}

};

struct stItemGen

{

stItemGen () { srand (time(0)); }

ClassItem* operator()()

{

switch(rand() % 3)

{

default:

case 0:

return new Class2;

case 1:

return new Class1;

case 2:

return new Class3;

}

}

};
struct GetCompete

{

Outcome operator()(ClassItem* ocObj, ClassItem* ocObj1)

{

cout << ocObj << "\t" << ocObj1 << "\t";

return ocObj->GetCompete(ocObj1);

}

};

int _tmain (int argc, _TCHAR* argv[])

{

  const int sz = 20;

vector<ClassItem*> v(sz*2);

generate(v.begin(), v.end(), stItemGen());

transform(v.begin(), v.begin() + sz,

v.begin() + sz,

//ostream_iterator<Outcome>(cout, "\n"),

GetCompete());

  getchar ();

 return 0;

}



No comments: