Game Development Reference
In-Depth Information
The code in
PrintNumberOfWheels
now accesses the
GetNumberOfWheels
methods of
Vehicle
,
Car
, and
Motorcycle
through a pointer to the
Vehicle
class. The output from this program is still
correct. The first
std::cout
will print 0, the second will print 4, and the third will print 2. This is
a perfect example of polymorphism in action: This code calls the
Car::GetNumberOfWheels
and
Motorcycle::GetNumberOfWheels
methods through a
Vehicle
pointer.
Once you begin to write more complex polymorphic programs you will find you'll need to cast to the
proper derived types in certain circumstances. C++ provides the
dynamic_cast
for these situations.
Downcasting and Upcasting with dynamic_cast
Moving between different types at runtime is usually an unsafe operation. In complex code it can
sometimes be difficult to be sure where pointers have come from, what they point to, and which
other classes exist in the class hierarchy for a given type. You should use
dynamic_cast
in these
situations to be sure that your code does not crash when converting between types. Listing 11-4
adds some code to
PrintNumberOfWheels
to show you how
dynamic_cast
can be used.
Listing 11-4. Using
dynamic_cast
to Downcast
void PrintNumberOfWheels()
{
Vehicle vehicle;
Car car;
Motorcycle motorcycle;
Vehicle* pVehicle = &vehicle;
std::cout << pVehicle->GetNumberOfWheels() << std::endl;
pVehicle = &car;
Car* pCar = dynamic_cast<Car*>(pVehicle);
if (pCar != nullptr)
{
std::cout << pCar->GetNumberOfWheels() << std::endl;
}
pVehicle = &motorcycle;
pCar = dynamic_cast<Car*>(pVehicle);
if (pCar != nullptr)
{
std::cout << pCar->GetNumberOfWheels() << std::endl;
}
}
Listing 11-4 has two
dynamic_cast
calls to convert the current value stored in
pVehicle
to a pointer
to a
Car
object. The result of a
dynamic_cast
can either be a valid pointer to the requested class or
nullptr
. This means that we must ensure that the result of a
dynamic_cast
is valid before trying to
dereference the resulting pointer or our application can crash. The first cast in Listing 11-4 results in
a valid pointer and therefore the number of wheels for a car will be printed out. The second cast will
fail and return
nullptr
. Both of these casts were attempts at a downcast. You can visualize a class