## Chapter 21 - Polymorphism

## Chapter Goals

- To be able to describe the information conveyed by a class hierarchy
- To understand the concept of the polymorphic variable and its relationship to class hierarchies
- To understand the interaction between polymorphism and memory management
- To understand how to distinguish between virtual and nonvirtual overriding and the uses of each
- To understand the concept of downcasting, moving both up and down the class hierarchy
- To understand the concept of multiple inheritance
- To learn how to design and use software frameworks

## 21.1 Class Inheritance Hierarchies

- Hierarchies often used to categorize concepts
- Often represented using trees:

## 21.1 Class Inheritance Hierarchies (cont.)

- The class inheritance relationship (is-a) fits this pattern
- Base classes at the top, derived classes below
- Each level linked to the object above by a is-a relationship
- Each derived class is more specialized

## 21.1 Class Inheritance Hierarchies (cont.)

- Some hierarchies are short:

- Forest vs. Tree

## 21.1 Class Inheritance Hierarchies (cont.)

- Others can be complex:

## 21.2 Polymorphic Variables

- Powerful mechanism in the OO paradigm
- Polymorphic - many forms
- Consider our `Employee` class:
  - add `annual_income` method
  - for `Employee`, this is equal to their yearly salary
  - inherit `Manager` from `Employee`
  - a `Manager's` annual income is the sum of their salary and bonus
  (Code on next slide)

## 21.2 Polymorphic Variables - example

>     class Employee
>     {
>     public:
>        Employee(string n, double s);
>        string get_name() const;
>        double get_salary() const;
>        void set_salary(double s);
>        virtual double annual_income() const;
>        void print(ostream& out) const;
>     private:
>        string name;
>        double salary;
>     };

## 21.2 Polymorphic Variables - example (cont.)

>     double Employee::annual_income() const
>     {
>        return get_salary();
>     }

>     class Manager : public Employee
>     {
>     public:
>        Manager(string n, double s, double b);
>        virtual double annual_income() const;
>     private:
>        double bonus;
>     };

## 21.2 Polymorphic Variables - example (cont.)

>     Manager::Manager(string n, double s, double b)
>        : Employee(n, s), bonus(b) {}

>     double Manager::annual_income() const
>     {
>        return get_salary() + bonus;
>     }

## 21.2 Polymorphic Variables (cont.)

- Pointer or reference declared with one type
- May hold a variable of a derived type:

  > `Employee* emp = new Manager("Sarah Smith", 67000, 2000);`

  - `Employee*` is the static type
  - `Manager*` is the dynamic type
- Dynamic type determined at run time

- Can change during execution

## 21.2 Polymorphic Variables - Dynamic Binding

- Power lies with dynamic binding
- A method invoked via polymorphic variable might execute the method of the dynamic type
- If the type changes during execution, so might the method selected

## 21.2 Polymorphic Variables - Dynamic Binding

- E.g., store members of a department in a vector of `Employee` pointers:

  > `vector<Employee*> department(3);
  > department[0] = new Manager("Sarah Smith", 67000, 2000);
  > department[1] = new Employee("Lisa Lim", 36000);
  > department[2] = new Employee("Harry Hacker", 42000);`

## 21.2 Polymorphic Variables - Dynamic Binding (cont.)

- Print out information regarding each employee:

  >     for (int i = 0; i < department.size(); i++)
  >     {
  >        cout << "Employee: "
  >           << department[i]->get_name() << " income "
  >           << department[i]->annual_income() << "\n";
  >     }

- Different `annual_income`s are being called:

  > `Employee Sarah Smith income 69000
  > Employee Lisa Lim income 36000
  > Employee Harry Hacker income 42000`

## 21.3 Virtual and Nonvirtual Overriding

- Override method in derived class
- Which method to execute:
  - statically bound - invoked through a static type
  - dynamically bound - invoked through a dynamic type

## 21.3 Virtual and Nonvirtual Overriding (cont.)

- If an object invokes an operation, statically bound:

  > `Employee e("Lisa Lim", 36000);
  > cout << e.annual_income() << "\n"; // Statically bound`

- If a virtual method is invoked through a pointer or a reference, it is bound dynamically:

  > `Employee* e = new Manager("Sarah Smith", 67000, 2000);
  > cout << e->get_salary() << "\n";
  > // Static binding, because get_salary is not virtual
  > cout << e->annual_income() << "\n";
  > // Dynamic binding, because annual_income is virtual`

## 21.3 Virtual and Nonvirtual Overriding (cont.)

- Methods invoked via `this` ptr follow same rules:

  >     void Employee::print(ostream& out) const
  >     {
  >        out << "Name " << get_name()
  >        // Static binding, same as Employee::get_name()
  >           << " income " << annual_income() << "\n";
  >           // Dynamic binding, same as this->annual_income()
  >     }

## 21.3 Virtual and Nonvirtual Overriding (cont.)

- The use of the dynamic type applies only to the selector of a member function
- Dynamic types of arguments are not considered in determination of a function for execution:

## 21.3 Virtual and Nonvirtual Overriding (cont.)

>     ostream& operator<<(ostream& out, const Employee& e)
>     {
>        out << "Employee " << e.name();
>        return out;
>     }

>     ostream& operator<<(ostream& out, const Manager& m)
>     {
>        out << "Manager " << e.name();
>        return out;
>     }

>     Manager man = new Manager(. . .);
>     cout << *man << "\n"; // Executes Manager function

## 21.3 Virtual and Nonvirtual Overriding (cont.)

- Passing an instance of a derived class might be confusing:

  >     void print(ostream& out, Employee& emp)
  >     {
  >        out << emp << "\n";
  >     }

  >     print(cout, *man);
  >        // Will print name as Employee not as Manager

- `emp`'s static type (`Employee`) is used to choose `operator<<`
- Try restructuring the flow of control (next slide):

## 21.3 Virtual and Nonvirtual Overriding (cont.)

- Better:

>     class Employee
>     {
>        . . .
>        virtual void print(ostream& out) const;
>     };

>     void Employee::print(ostream& out) const
>     {
>        out << "Employee " << name();
>     }

## 21.3 Virtual and Nonvirtual Overriding (cont.)

>     class Manager : public Employee
>     {
>        . . .
>        virtual void print(ostream& out) const;
>     };

>     void Manager::print(ostream& out) const
>     {
>        out << "Manager " << name();
>     }

>     ostream& operator<<(ostream& out, const Employee& e)
>     {
>        e.print(out);
>        return out;
>     }

## 21.3 Virtual and Nonvirtual Overriding (cont.)

- One `operator<<`, takes a reference to a base class
- Uses a reference selector to call the virtual print method:

  > `Employee* emp = new Employee("Fred Jones", 67000);
  > cout << emp << "\n";`

  prints: `Employee Fred Jones.`

  > `emp = new Manager("Sarah Smith", 82000);
  > cout << emp << "\n";`

  prints: `Manager Sarah Smith.`

## 21.3 Virtual and Nonvirtual Overriding - wrapup

Retain the `virtual` Keyword
  Once declared `virtual`, a method remains virtual in all derived classes
Heterogeneous Collections
  A vector of pointers can store values of any derived type
Include Virtual Destructors
  If a class has a virtual method, define a virtual d'tor

## 21.4 Pure Virtual Member Functions

- abstract class: contains a pure virtual method
- Provides an i/f, but no behavior
- Cannot be instantiated
- Used only as a base class for inheritance
- E.g., compute the area of a shape:
  - `Shape` must declare an `area` method
  - Can't define it
  - Each derived class has an `area` method
- interface - class where all methods are pure virtual

## 21.4 Pure Virtual Member Functions (cont.)

Syntax 21.1: Pure Virtual Member Function
    class ClassName
    {
       . . .
       virtual return_type function_name(parameters) = 0;
       . . .
    };
Example: |
    class Shape
    {
       . . .
       virtual double area() const = 0;
    };

## 21.4 Pure Virtual Member Functions (cont.)

Syntax 21.1: Pure Virtual Member Function (cont.)
Purpose: | Declare a member function with no definition. A class that contains at least one pure virtual function is termed abstract. Derived classes must either override the function and provide their own definition or they themselves will be considered abstract.

## 21.5 Obtaining Run-Time Typing Information (RTTI)

2 common ways to obtain the dynamic type of an object:

1. dynamic cast - for casting down the inheritance hierarchy, checking for success
2. Using the `type_id` operator to compare a dynamic type to a known type

Warning: use virtual methods instead of RTTI and complex conditionals

## 21.5 (cont.) RTTI - the Dynamic Cast

Syntax 21.2: Dynamic Cast
    dynamic_cast<type_name>(expression)
Example: |
    Employee* e = new Manager("Sarah Smith", 67000, 2000);
    Manager* m = dynamic_cast<Manager*>(e);
Purpose: | Safely test the type of a polymorphic variable, converting to a derived class type if appropriate, returning a `Null` pointer if not.

## 21.5 (cont.) RTTI - the Dynamic Cast

- For casting down the inheritance hierarchy.
- Takes a pointer or reference
- Returns the dynamic type of the argument, if it matches the type parameter
- Otherwise, returns `NULL` (for pointer), or throws `bad_cast`
- `static_cast` performs no run-time check

## 21.5 (cont.) RTTI - the Dynamic Cast

- Check return type to test type:

>     for (int i = 0; i < department.size(); i++)
>     {
>        Manager* m = dynamic_cast<Manager*>(department[i]);
>           if (m != NULL)
>              cout << "Employee " << department[i]->get_name()
>                 << " is a manager.\n";
>        else
>           cout << "Employee " << department[i]->get_name()
>              << " is not a manager.\n";
>     }

## 21.5.1 The `typeid` Operator

Syntax 21.3: `typeid`
    typeid(expression)
    typeid(type_name)
Example: |
    #include <typeinfo>
    typeid(*department[i]).name();
    if (typeid(*department[i]) == typeid(Manager)) . . .
Purpose: | Obtain dynamic type information from a polymorphic expression.

## 21.5.1 The `typeid` Operator (cont.)

- More general facility
- Takes either an expression or a class name (type)
- Returns a `type_info`, defined in `<typeinfo>`

## 21.5.1 The `typeid` Operator (cont.)

- Contains class name, as a string:

  >     for (int i = 0; i < department.size(); i++)
  >        cout << typeid(*department[i]).name() << "\n";

  will produce

  > `Manager
  > Employee
  > Employee`

## 21.5.1 The `typeid` Operator (cont.)

- Another way to test an object's type
- Compare its `typeinfo` value to that of a known type:

  >     for (int i = 0; i < department.size(); i++)
  >     {
  >        if (typeid(*department[i]) == typeid(Manager))
  >           cout << "Employee " << department[i]->get_name()
  >              << " is a manager. \n";
  >        else
  >           cout << "Employee " << department[i]->get_name()
  >              << " is not a manager. \n";
  >     }

- Warning: Comparisons between types and pointers will always fail

## 21.6 Slicing and Polymorphism

- Layout of objects on the stack is determined at compile time
- C++ used different rules for pointers than for objects
- Only pointers (and references) are truly polymorphic:

  >     Employee e("Lisa Lim", 36000);
  >     Manager m("Sarah Smith", 67000, 2000);
  >     e = m; // Permitted, but manager fields sliced away
  >     cout << e.annual_income() << "\n";
  >        // Uses Employee member function

## 21.7 Muliple Inheritance

- The real world is not so neatly categorized
- Consider a class `TeachingAssistant`
  - Exhibits characteristics of both `Employee` and `Student`
- C++ provides for multiple inheritance:

## 21.7 Muliple Inheritance (cont.)

- Directed acyclic graph: a class cannot be an ancestor of itself

## 21.7 Muliple Inheritance (cont.)

Syntax 21.4: Multiple Inheritance
    class DerivedClassName : public BaseClass1, . . . public BaseClassn
Example: |
    class TeachingAssistant : public Student, public Employee
    {
       . . .
    }
Purpose: | Define a class that inherits features from two or more base classes.

## 21.7 Muliple Inheritance (cont.)

- Instances of derived classes maintain data fields of all base classes:

## 21.7 Muliple Inheritance (cont.)

- The idea of polymorphic assignment applies for each of the base classes:

  > `TeachingAssistant* fred = new TeachingAssistant();
  > Employee* new_hire = fred; // Legal, because a TeachingAssistant is-a Employee
  > Student* advisee = fred; // Legal, because a TeachingAssistant is-a Student`

## 21.7 Muliple Inheritance (cont.)

- Dynamic cast and `typeid` work just as we'd like:

  >     Student* mary = . . .;
  >     TeachingAssistant* lab_instructor
  >        = dynamic_cast<TeachingAssistant*>(mary);
  >     if (lab_instructor != NULL)
  >        cout << "Yes, mary is a TeachingAssistant. \n";
  >     else
  >        cout << "No, mary is not a TeachingAssistant. \n";

## 21.7.1 Name Ambiguity

- Names of inherited operations may clash
- E.g., suppose both `Employee` and `Student` provide a `get_id` method, that refer to different IDs:

  > `TeachingAssistant* fred = new TeachingAssistant();
  > cout << "Your number is " << fred->get_id() << "\n";
  > // Error, ambiguous member function name`

- 2 resolutions:

## 21.7.1 Name Ambiguity (cont.)

1. Use the fully qualified function name:

   > `cout << "Your teaching assistant is "
   > << fred->Employee::get_id() << "\n";`

## 21.7.1 Name Ambiguity (cont.)

2. Redefine the ambiguous name in the new class:

   >     class TeachingAssistant : public Student, public Employee
   >     {
   >     public:
   >        string get_id() const;
   >        string student_id() const;
   >     };

## 21.7.1 Name Ambiguity (cont.)

- Hide the use of the qualified name within the body

>     // get_id will return Employee identification number
>     string TeachingAssistant::get_id()
>     {
>        return Employee::get_id();
>     }

>     string TeachingAssistant::student_id()
>     	// Make student value available by a different name
>     {
>        return Student::get_id();
>     }

## 21.7.2 Replicated Base Classes

- Base class is specified only once
- A class may be inherited (indirectly) more than once
- E.g., `Person` as a base class for `Employee` and `Student`:

  >     class Person
  >     {
  >     public:
  >        Person(string n);
  >        string get_name() const;
  >     private:
  >        string name;
  >     };

## 21.7.2 Replicated Base Classes

>     class Employee : public Person
>     {
>        . . .
>     };

>     class Student : public Person
>     {
>        . . .
>     };

## 21.7.2 Replicated Base Classes (cont.)

- `TeachingAssistant` now has 2 `name` fields:

## 21.7.2 Replicated Base Classes (cont.)

- If this is not desirable, specify inheritance as `virtual`:

  >     class Student : virtual public Person
  >     {
  >        . . .
  >     };

  >     class Employee : virtual public Person
  >     {
  >        . . .
  >     };

  >     class TeachingAssistant : public Student, public Employee
  >     {
  >        . . .
  >     };

## 21.7.2 Replicated Base Classes (cont.)

- The intermediate classes need to use virtual inheritance
- Virtual inheritance alters placement of base classes

## 21.7.2 Replicated Base Classes (cont.)

- Duplicated data areas from the common base class are eliminated:

## 21.7.2 Replicated Base Classes (cont.)

- `TeachingAssistant*` can always be converted to an `Employee*`, then to a `Person*`
- Without virtual inheritance, a `TeachingAssistant*` can not be converted directly to a `Person*`:

  > `TeachingAssistant* fred = new TeachingAssistant();
  > Student* s = fred; // Legal, because TeachingAssistant is-a Student
  > Person* p1 = s;
  > Employee* e = fred;
  > Person* p2 = e;
  > Person* p3 = fred; // Legal if virtual inheritance used, otherwise error`

## 21.8 Software Frameworks

- Modern programming emphasized software reuse
- A reusable component must be general purpose
- Details of an individual application are required
- Polymorphism provides a handy solution:
  - A general base class is developed and distributed across many projects
  - Use Inheritance to create specialized versions of the general base class

## 21.8 Software Frameworks (cont.)

- Consider the creation of GUI:

- Many different components
- Each component may have complex behavior

- Rewriting this behavior for each new application would be difficult
- Programmers employ a software framework, or toolkit:

- Collection of reusable classes and functions
- A starting point used in the creation of new applications

## 21.8 Software Frameworks (cont.)

Consider putting a window up on a screen. The concept of window is generic.

- Put code to handle generic tasks, such as moving the window, in the base class
- For application-aware tasks, base class provides simple default behavior or pure virtual functions:

## 21.8 Software Frameworks (cont.)

>     class wxWindow
>     {
>     public:
>        . . .
>        // Pure virtual member function
>        virtual void OnPaint(wxPaintEvent& event) = 0;
>        virtual void OnMouseEvent(wxMouseEvent& event);
>        . . .
>     };

>     void wxWindow::OnMouseEvent(wxMouseEvent& event)
>     {
>        // Default behavior, do nothing
>     }

## 21.8 Software Frameworks (cont.)

- Each new application inherits from `wxWindow` to create a special purpose class
- Application-specific details can be filled in:

## 21.8 Software Frameworks (cont.)

>     class ClockWindow : public wxWindow
>        // ClockWindow will be developed in Chapter 27
>     {
>     public:
>        . . .
>        virtual void OnPaint(wxPaintEvent& event);
>        virtual void OnMouseEvent(wxMouseEvent& event);
>        . . .
>     };

>     void ClockWindow::OnMouseEvent(wxMouseEvent& event)
>     {
>        . . . // Implement mouse events for this specific application
>     }

## Chapter Summary

1. Inheritance can be used to organize classes into hierarchies.
2. Polymorphic variables are very powerful. Declared as one type, its static type, but can maintain a value of a different type, its dynamic type. Must be pointers or references.
3. When a virtual method is called using a polymorphic variable, its dynamic type is used.
4. A virtual method that is declared but not defined is called a pure virtual method. A class with a pure virtual method can not be instantiated. It is called an abstract class.

## Chapter Summary (cont.)

5. The dynamic type of a polymorphic variable can be tested using a dynamic cast, or the `typeid` operator.
6. A class that inherits from two or more base classes is said to use multiple inheritance.
7. A software framework (or toolkit) is a collection of classes and/or functions that capture the common features of a task. Methods are overridden to specialize behavior.