Dissecting Code

Wednesday, March 13, 2013

Static type resolution and double-dispatch

Double dispatch is required due to the same reasons as mentioned  here. The fact that overload resolution is done with the static type leads to issues such as the call to a.collideWith shown below, and double dispatch provides a solution to this - look at the call to s.collideWith(a) and the associated sequence of operations in the subsequent comment.

//Double dispatch as mentioned @ http://en.wikipedia.org/wiki/Double_dispatch
#include <iostream>

using namespace std;

class SpaceShip;
class MySpaceShip;

class Asteroid
{
public:
    virtual void collideWith(SpaceShip&)
    {
        cout<<"Asteroid Collided with SpaceShip";
    }

    virtual void collideWith(MySpaceShip&)
    {
        cout<<"Asteroid Collided with mySpaceShip";
    }
};

class MyAsteroid : public Asteroid
{
public:
    void collideWith(SpaceShip&) override
    {
        cout<<"My asteroid collided with spaceShip";
    }

    void collideWith(MySpaceShip &) override
    {
        cout<<"My asteroid collided with mySpaceShip";
    }
};

class SpaceShip
{
public:
    virtual void collideWith(Asteroid& a)
    {
        a.collideWith(*this);
    }
};

class MySpaceShip : public SpaceShip
{
public:
    void collideWith(Asteroid& a) override
    {
        a.collideWith(*this);
    }
};

int main(int argc, char *argv[])
{
    MyAsteroid m;
    Asteroid& a = m;
    MySpaceShip myS;
    SpaceShip &s = myS;
    a.collideWith(s); //overloading is done by static
                      //type -> vfptr lookup, 
                      //myAsteroid.collideWith(Asteroid&)

    s.collideWith(a); //double-dispatch operates -> 
                      //vfptr lookup, 
                      //myspaceShip.collideWith(Asteroid&), 
                      //typeof(*this) = MySpaceShip,
                      //vfptr lookup, 
                      //myAsteroid.collideWith(MySpaceShip&)
    return 0;
}

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]



<< Home