The following will race a Bicycle
with a Vehicle
:
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
aBicycle->raceWith(aCar);
To race a Bicycle
with a Car
we need to use double dispatch.
To make double dispatch work we use the this
pointer to call the next function so that the second virtual call can resolve to the correct type of vehicle:
class Car;
class Bicycle;
class Vehicle {
public:
virtual bool raceWith(Vehicle& anotherVehicle) = 0;
virtual bool raceWith(Bicycle& anotherVehicle) = 0;
virtual bool raceWith(Car& anotherVehicle) = 0;
};
class Bicycle : public Vehicle {
public:
virtual bool raceWith(Vehicle& anotherVehicle) override
{
//throw std::exception();
return anotherVehicle.raceWith(*this);
}
virtual bool raceWith(Car& anotherVehicle)
{
return true;
}
virtual bool raceWith(Bicycle& anotherVehicle)
{
return false;
}
};
class Car : public Vehicle {
public:
virtual bool raceWith(Vehicle& anotherVehicle) override
{
return true;
}
virtual bool raceWith(Car& anotherVehicle) override
{
return true;
}
virtual bool raceWith(Bicycle& anotherVehicle) override
{
return false;
}
};
int main()
{
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
aBicycle->raceWith(*aCar);
}
Note the return anotherVehicle.raceWith(*this);
which will perform the second virtual call.
The functions are then called in this order:
main();
Bicycle::raceWith(Vehicle& anotherVehicle);
Car::raceWith(Bicycle& anotherVehicle);
The following is the same program, but sticking with the use of pointers and exceptions as provided in the question:
#include <exception>
class Car;
class Bicycle;
class Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) = 0;
virtual bool raceWith(Bicycle* bicycle) = 0;
virtual bool raceWith(Car* car) = 0;
};
class Bicycle : public Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) override
{
//throw std::exception();
return anotherVehicle->raceWith(this);
}
virtual bool raceWith(Car* car) override
{
return true;
}
virtual bool raceWith(Bicycle* bicycle) override
{
return false;
}
};
class Car : public Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) override
{
throw std::exception();
}
virtual bool raceWith(Car* car) override
{
return true;
}
virtual bool raceWith(Bicycle* bicycle) override
{
return false;
}
};
int main()
{
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
aBicycle->raceWith(aCar);
}