Polymorphism  «Prev  Next»
Lesson 11

Using Polymorphism Conclusion

In this module you learned about the concept of polymorphism and why it is essential to designing code that requires little modification when functionality is added.
You learned:
  1. What ad hoc polymorphism is and why it is useful
  2. About the two types of ad hoc polymorphism: conversion and overloading
  3. How to create special conversion member functions to convert from a user-defined type to a built-in type
  4. How the compiler picks the appropriate version of an overloaded function

One of the key features of derived classes is that a pointer to a derived class is type-compatible with a pointer to its base class. Polymorphism is the art of taking advantage of this simple but powerful and versatile feature, that brings Object Oriented Methodologies to its full potential.
Polymorphism (literally, having multiple shapes) describes a set of objects of different classes with similar behavior.

Virtual Functions and Polymorphism

Suppose you are not sure whether a computer referenced in a program will be a laptop or a regular computer. Because of your uncertainty, you cannot declare a variable of either type to store the data for that computer. However, if you declare the pointer variable
Computer* the_computer;

you can use it to reference an object of either type, because a type Lap_Top object can be referenced by a type Computer* variable. In C++ a pointer variable of a baseclass type (general) can point to an object of a derived-class type (specific). Lap_Top objects are Computer objects with more features.
Now suppose you have purchased a laptop computer.
Question: What happens when the following statements are executed?
the_computer = new Lap_Top("Bravo", "Intel P4 2.4", 256, 40, 15.0, 7.5);
cout <<  the_computer->to_string() << endl;
Will the function call the_computer->to_string() return a string with all six data fields for a Lap_Top object (using Lap_Top::to_string) or just the four data fields defined for a Computer object (using Computer::to_string)? The answer is a string with just the four data fields because the_computer is type pointer-to-Computer. This is not what we want/
What we want is for the type of the object receiving the to_string message to determine which to_string member function is called. We can tell C++ that this is what we want by changing the declaration of the function to_string in the class Computer (in Computer.h) to a virtual function:
virtual std::string to_string() const;

If a member function is declared virtual, then when it is called through a pointer (or reference) variable the actual member function will be determined at run time and based on the type of the object pointed to (or referenced). For example, if the variable the_computer points to a Lap_Top object, then the expression
the_computer->to_string()
will call the member function to_string that is defined by the Lap_Top class.
The fact that the to_string member function invoked depends on the type of the object pointed to, and not the type of the pointer variable (the_computer is type pointer-to-Computer), is a very important feature of object-oriented programming languages. This feature is called polymorphism, which means
the quality of having many forms or many shapes.

Polymorphism enables the program to determine which member function to invoke at run time. At compile time, the C++ compiler cannot determine what type of object the_computer will point to (type Computer or its derived type Lap_Top), but at run time the program knows the type of the object that receives the to_string message and can call the appropriate to_string function.