Game Development Reference
In-Depth Information
hierarchy as having the base class at the top and all child classes below that. Casting from a higher
class to a lower class is a downcast and the opposite is an upcast. The code in Listing 11-5 is safer
than the code in Listing 11-4, as we use
dynamic_cast
to upcast to the
Vehicle
pointer.
Listing 11-5. Upcasting
void PrintNumberOfWheels()
{
Vehicle vehicle;
Car car;
Motorcycle motorcycle;
Vehicle* pVehicle = dynamic_cast<Vehicle*>(
&
vehicle);
std::cout << pVehicle->GetNumberOfWheels() << std::endl;
pVehicle = dynamic_cast<Vehicle*>(
&
car);
Car* pCar = dynamic_cast<Car*>(pVehicle);
if (pCar != nullptr)
{
std::cout << pCar->GetNumberOfWheels() << std::endl;
}
pVehicle = dynamic_cast<Vehicle*>(
&
motorcycle);
pCar = dynamic_cast<Car*>(pVehicle);
if (pCar != nullptr)
{
std::cout << pCar->GetNumberOfWheels() << std::endl;
}
}
The upcasts to
Vehicle
in Listing 11-5 are all much safer than the previous implicit casts. This would
not matter too much in this example code, as we know all of the objects derive from
Vehicle
, but in
production code you might not be able to guarantee that a given pointer derives from a specific
base class.
Creating Interfaces with Pure Virtual Methods
The
Vehicle
class has a value to return for
GetNumberOfWheels
. In a proper program it would be
unlikely that we would want to be able to create basic
Vehicle
objects as we are more likely to want
to create instances of
Car
or
Motorcycle
. It also makes little sense for a
Vehicle
to have any number
of wheels, even none. We can turn
Vehicle
into an interface by making its
GetNumberOfWheels
class a
pure virtual method. Listing 11-6 shows how to do this.
Listing 11-6. Making Pure Virtual Methods
class Vehicle
{
public:
virtual unsigned int GetNumberOfWheels() const = 0;
};