0

I didn't fully understand object slicing in C++. With the following example code two objects seem to receive the same processing, but polymorphism works for only one of them.

I'm using references and one of the objects doesn't seem to be sliced. I believe something must happen during the launch_ship function call, but I don't know exactly what is going wrong.

Here is the example code.

#include <iostream>


class SpaceShip
{};

class MilleniumFalcon: public SpaceShip
{};

class Pilot
{
public:
     virtual void operate(SpaceShip&)
    {
        std::cerr << "Operating spaceship" << std::endl;
    }

    virtual void operate(MilleniumFalcon&)
    {
        std::cerr << "Cannot operate that spaceship!" << std::endl;
    }
};

class Chewbacca: public Pilot
{
public:
    virtual void operate(SpaceShip&)
    {

        std::cerr << "Don't want to operate that low spaceship!" <<
                  std::endl;
    }

    virtual void operate(MilleniumFalcon&)
    {
         std::cerr << "Operating the Millenium Falcon" << std::endl;
    }
};

void launch_ship(Pilot& pilot, SpaceShip& ship)
{
      pilot.operate(ship);
}

int main()
{
    Chewbacca chewie;
    MilleniumFalcon millenium;

    launch_ship(chewie, millenium);
}

output : Don't want to operate that low spaceship!

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Calimero
  • 161
  • 1
  • 8
  • 1
    Note: it's not so cool after Jarod took the time to answer your Star Wars example to change it into an animal/hero one. This site wants posterity for questions and answers (so that they may help not only you but future people as well), so it's kind of confusing to change your example source code from Star Wars into like an RPG NPC example. My suggestion is kind of keep it as it was before unless you really have to change it to something else. –  Nov 24 '15 at 13:39
  • @Ike Didn't see the answer, i thought it was safe to change it. Will change back when i come back – Calimero Nov 24 '15 at 13:41
  • Cheers -- also if you want to include that animal/hero kind of fighting example, you can edit it and add it below the Star Wars one. But try to avoid desyncing your question from the answers if you can to avoid confusion for future readers. –  Nov 24 '15 at 13:43

1 Answers1

3

There are no slicing here.

C++ uses single dispatch and not multiple dispatch.

The dispatch done by virtual is done only with this instance.

so in

pilot.operate(ship);

there is only a dispatch with pilot (and use dynamic type of pilot), but we use static type of ship (so SpaceShip&)

You have to use visitor or implement yourself a multiple dispatch.

For example:

class SpaceShip
{
public:
    virtual void operate_by(Pilot& pilot) { pilot.operate(*this); }
};

class MilleniumFalcon: public SpaceShip
{
public:
    virtual void operate_by(Pilot& pilot) override { pilot.operate(*this); }
};


void launch_ship(Pilot& pilot, SpaceShip& ship)
{
    ship.operate_by(pilot);
}

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302