#

#

- Day 13
  - Polymorphism
    - Problems with Single Inheritance
    - Listing 13.1. If horses could fly...
      - Percolating Upward
      - Casting Down
    - Listing 13.2. Casting down.
      - Adding to Two Lists
    - Multiple Inheritance
    - Listing 13.3. Multiple inheritance.
    - Declaring Multiple Inheritance
      - The Parts of a Multiply Inherited Object
        - Figure 13.1.
      - Constructors in Multiply Inherited Objects
    - Listing 13.4. Calling multiple constructors.
      - Ambiguity Resolution
      - Inheriting from Shared Base Class
        - Figure 13.2.
    - Listing 13.5. Common base classes.
      - Virtual Inheritance
        - Figure 13.3.
    - Listing 13.6. Illustration of the use of virtual inheritance.
    - Declaring Classes for Virtual Inheritance
      - Problems with Multiple Inheritance
      - Mixins and Capabilities Classes
    - Abstract Data Types
    - Listing 13.7. Shape classes.
      - Pure Virtual Functions
    - Listing 13.8. Abstract Data Types.
    - Abstract Data Types
      - Implementing Pure Virtual Functions
    - Listing 13.9. Implementing pure virtual functions.
      - Complex Hierarchies of Abstraction
    - Listing 13.10. Deriving ADTs from other ADTs.
      - Which Types Are Abstract?
    - The Observer Pattern
      - A Word About Multiple Inheritance, Abstract Data Types, and Java
    - Summary
    - Q&A
    - Workshop
      - Quiz
      - Exercises

## Day 13

## Polymorphism

Yesterday, you learned how to write virtual functions in derived classes. This is the fundamental building block of polymorphism: the capability to bind specific, derived class objects to base class pointers at runtime. Today, you learnWhat multiple inheritance is and how to use it.

- What virtual inheritance is.

- What abstract data types are.

- What pure virtual functions are.

### Problems with Single Inheritance

Suppose you've been working with your animal classes for a while and you've divided the class hierarchy into `Birds` and `Mammals`. The `Bird` class includes the member function `Fly()`. The `Mammal` class has been divided into a number of types of `Mammal`s, including `Horse`. The `Horse` class includes the member functions `Whinny()` and `Gallop()`.

Suddenly, you realize you need a `Pegasus` object: a cross between a `Horse` and a `Bird`. A `Pegasus` can `Fly()`, it can `Whinny()`, and it can `Gallop()`. With single inheritance, you're in quite a jam.

You can make `Pegasus` a `Bird`, but then it won't be able to `Whinny()` or `Gallop()`. You can make it a `Horse`, but then it won't be able to `Fly()`.

Your first solution is to copy the `Fly()` method into the `Pegasus` class and derive `Pegasus` from `Horse`. This works fine, at the cost of having the `Fly()` method in two places (`Bird` and `Pegasus`). If you change one, you must remember to change the other. Of course, a developer who comes along months or years later to maintain your code must also know to fix both places.

Soon, however, you have a new problem. You wish to create a list of `Horse` objects and a list of `Bird` objects. You'd like to be able to add your `Pegasus` objects to either list, but if a `Pegasus` is a horse, you can't add it to a list of birds.

You have a couple of potential solutions. You can rename the `Horse` method `Gallop()` to `Move()`, and then override `Move()` in your `Pegasus` object to do the work of `Fly()`. You would then override `Move()` in your other horses to do the work of `Gallop()`. Perhaps `Pegasus` could be clever enough to gallop short distances and fly longer distances.

    Pegasus::Move(long distance)
    {
    if (distance > veryFar)
    fly(distance);
    else
    gallop(distance);
    }

This is a bit limiting. Perhaps one day `Pegasus` will want to fly a short distance or gallop a long distance. Your next solution might be to move `Fly()` up into `Horse`, as illustrated in Listing 13.1. The problem is that most horses can't fly, so you have to make this method do nothing unless it is a `Pegasus`.

Listing 13.1. If horses could fly...

    1:     // Listing 13.1. If horses could fly...
    2:     // Percolating Fly() up into Horse
    3:
    4:     #include <iostream.h>
    5:
    6:     class Horse
    7:     {
    8:     public:
    9:        void Gallop(){ cout << "Galloping...\n"; }
    10:       virtual void Fly() { cout << "Horses can't fly.\n" ; }
    11:    private:
    12:       int itsAge;
    13:    };
    14:
    15:    class Pegasus : public Horse
    16:    {
    17:    public:
    18:       virtual void Fly() { cout << "I can fly! I can fly! I can fly!\n"; }
    19:    };
    20:
    21:    const int NumberHorses = 5;
    22:    int main()
    23:    {
    24:       Horse* Ranch[NumberHorses];
    25:       Horse* pHorse;
    26:       int choice,i;
    27:       for (i=0; i<NumberHorses; i++)
    28:       {
    29:          cout << "(1)Horse (2)Pegasus: ";
    30:          cin >> choice;
    31:          if (choice == 2)
    32:             pHorse = new Pegasus;
    33:          else
    34:             pHorse = new Horse;
    35:          Ranch[i] = pHorse;
    36:       }
    37:       cout << "\n";
    38:       for (i=0; i<NumberHorses; i++)
    39:       {
    40:          Ranch[i]->Fly();
    41:          delete Ranch[i];
    42:       }
    43:     return 0;
    44: }

    Output: (1)Horse (2)Pegasus: 1
    (1)Horse (2)Pegasus: 2
    (1)Horse (2)Pegasus: 1
    (1)Horse (2)Pegasus: 2
    (1)Horse (2)Pegasus: 1

    Horses can't fly.
    I can fly! I can fly! I can fly!
    Horses can't fly.
    I can fly! I can fly! I can fly!
    Horses can't fly.

Analysis: This program certainly works, though at the expense of the `Horse` class having a `Fly()` method. On line 10, the method`Fly()` is provided to `Horse`. In a real-world class, you might have it issue an error, or fail quietly. On line 18, the `Pegasus` class overrides the `Fly()` method to "do the right thing," represented here by printing a happy message.

The array of `Horse` pointers on line 24 is used to demonstrate that the correct `Fly()` method is called based on the runtime binding of the `Horse` or `Pegasus` object.

#### Percolating Upward

Putting the required function higher in the class hierarchy is a common solution to this problem and results in many functions "percolating up" into the base class. The base class is then in grave danger of becoming a global namespace for all the functions that might be used by any of the derived classes. This can seriously undermine the class typing of C++, and can create a large and cumbersome base class.

In general, you want to percolate shared functionality up the hierarchy, without migrating the interface of each class. This means that if two classes that share a common base class (for example, `Horse` and `Bird` both share `Animal`) have a function in common (both birds and horses eat, for example), you'll want to move that functionality up into the base class and create a virtual function.

What you'll want to avoid, however, is percolating an interface (like `Fly` up where it doesn't belong), just so you can call that function only on some derived classes.

#### Casting Down

An alternative to this approach, still within single inheritance, is to keep the `Fly()` method within `Pegasus`, and only call it if the pointer is actually pointing to a `Pegasus` object. To make this work, you'll need to be able to ask your pointer what type it is really pointing to. This is known as Run Time Type Identification (RTTI). Using RTTI has only recently become an official part of C++.

If your compiler does not support RTTI, you can mimic it by putting a method that returns an enumerated type in each of the classes. You can then test that type at runtime and call `Fly()` if it returns `Pegasus`.

> NOTE: Beware of adding RTTI to your classes. Use of it may be an indication of poor design. Consider using virtual functions, templates, or multiple inheritance instead.

In order to call `Fly()` however, you must cast the pointer, telling it that the object it is pointing to is a `Pegasus` object, not a `Horse`. This is called casting down, because you are casting the `Horse` object down to a more derived type.

C++ now officially, though perhaps reluctantly, supports casting down using the new `dynamic_cast` operator. Here's how it works.

If you have a pointer to a base class such as `Horse`, and you assign to it a pointer to a derived class, such as `Pegasus`, you can use the `Horse` pointer polymorphically. If you then need to get at the `Pegasus` object, you create a `Pegasus` pointer and use the `dynamic_cast` operator to make the conversion.

At runtime, the base pointer will be examined. If the conversion is proper, your new `Pegasus` pointer will be fine. If the conversion is improper, if you didn't really have a `Pegasus` object after all, then your new pointer will be null. Listing 13.2 illustrates this point.

Listing 13.2. Casting down.

    1:     // Listing 13.2 Using dynamic_cast.
    2:     // Using rtti
    3:
    4:     #include <iostream.h>
    5:     enum TYPE { HORSE, PEGASUS };
    6:
    7:     class Horse
    8:     {
    9:     public:
    10:       virtual void Gallop(){ cout << "Galloping...\n"; }
    11:
    12:    private:
    13:       int itsAge;
    14:    };
    15:
    16:    class Pegasus : public Horse
    17:    {
    18:    public:
    19:
    20:       virtual void Fly() { cout << "I can fly! I can fly! I can fly!\n"; }
    21:    };
    22:
    23:    const int NumberHorses = 5;
    24:    int main()
    25:    {
    26:       Horse* Ranch[NumberHorses];
    27:       Horse* pHorse;
    28:       int choice,i;
    29:       for (i=0; i<NumberHorses; i++)
    30:       {
    31:          cout << "(1)Horse (2)Pegasus: ";
    32:          cin >> choice;
    33:          if (choice == 2)
    34:             pHorse = new Pegasus;
    35:          else
    36:             pHorse = new Horse;
    37:          Ranch[i] = pHorse;
    38:       }
    39:       cout << "\n";
    40:       for (i=0; i<NumberHorses; i++)
    41:       {
    42:          Pegasus *pPeg = dynamic_cast< Pegasus *> (Ranch[i]);
    42:          if (pPeg)
    43:             pPeg->Fly();
    44:          else
    45:             cout << "Just a horse\n";
    46:
    47:          delete Ranch[i];
    48:       }
    49:  return 0;
    50:

    Output: (1)Horse (2)Pegasus: 1
    (1)Horse (2)Pegasus: 2
    (1)Horse (2)Pegasus: 1
    (1)Horse (2)Pegasus: 2
    (1)Horse (2)Pegasus: 1

    Just a horse
    I can fly! I can fly! I can fly!
    Just a horse
    I can fly! I can fly! I can fly!
    Just a horse

Analysis: This solution also works. `Fly()` is kept out of `Horse`, and is not called on `Horse` objects. When it is called on `Pegasus` objects, however, they must be explicitly cast; `Horse` objects don't have the method `Fly()`, so the pointer must be told it is pointing to a `Pegasus` object before being used.

The need for you to cast the `Pegasus` object is a warning that something may be wrong with your design. This program effectively undermines the virtual function polymorphism, because it depends on casting the object to its real runtime type.

#### Adding to Two Lists

The other problem with these solutions is that you've declared `Pegasus` to be a type of `Horse`, so you cannot add a `Pegasus` object to a list of `Birds`. You've paid the price of either moving `Fly()` up into `Horse`, or casting down the pointer, and yet you still don't have the full functionality you need.

One final single inheritance solution presents itself. You can push `Fly()`, `Whinny()`, and `Gallop()` all up into a common base class of both `Bird` and `Horse`: `Animal`. Now, instead of having a list of `Bird`s and a list of `Horse`s, you can have one unified list of `Animal`s. This works, but percolates more functionality up into the base classes.

Alternatively, you can leave the methods where they are, but cast down `Horses` and `Birds` and `Pegasus` objects, but that is even worse!

> DO move functionality up the inheritance hierarchy. DON'T move interface up the inheritance hierarchy. DO avoid switching on the runtime type of the object--use virtual methods, templates, and multiple inheritance. DON'T cast pointers to base objects down to derived objects.

### Multiple Inheritance

It is possible to derive a new class from more than one base class. This is called Multiple Inheritance. To derive from more than the base class, you separate each base class by commas in the class designation. Listing 13.3 illustrates how to declare `Pegasus` so that it derives from both `Horses` and `Birds`. The program then adds `Pegasus` objects to both types of lists.

Listing 13.3. Multiple inheritance.

    1:     // Listing 13.3. Multiple inheritance.
    2:     // Multiple Inheritance
    3:
    4:     #include <iostream.h>
    5:
    6:     class Horse
    7:     {
    8:     public:
    9:        Horse() { cout << "Horse constructor... "; }
    10:       virtual ~Horse() { cout << "Horse destructor... "; }
    11:       virtual void Whinny() const { cout << "Whinny!... "; }
    12:    private:
    13:       int itsAge;
    14:    };
    15:
    16:    class Bird
    17:    {
    18:    public:
    19:       Bird() { cout << "Bird constructor... "; }
    20:       virtual ~Bird() { cout << "Bird destructor... "; }
    21:       virtual void Chirp() const { cout << "Chirp... ";  }
    22:       virtual void Fly() const
    23:       {
    24:          cout << "I can fly! I can fly! I can fly! ";
    25:       }
    26:    private:
    27:       int itsWeight;
    28:    };
    29:
    30:    class Pegasus : public Horse, public Bird
    31:    {
    32:    public:
    33:       void Chirp() const { Whinny(); }
    34:       Pegasus() { cout << "Pegasus constructor... "; }
    35:       ~Pegasus() { cout << "Pegasus destructor...  "; }
    36:    };
    37:
    38:    const int MagicNumber = 2;
    39:    int main()
    40:    {
    41:       Horse* Ranch[MagicNumber];
    42:       Bird* Aviary[MagicNumber];
    43:       Horse * pHorse;
    44:       Bird * pBird;
    45:       int choice,i;
    46:       for (i=0; i<MagicNumber; i++)
    47:       {
    48:          cout << "\n(1)Horse (2)Pegasus: ";
    49:          cin >> choice;
    50:          if (choice == 2)
    51:             pHorse = new Pegasus;
    52:          else
    53:             pHorse = new Horse;
    54:          Ranch[i] = pHorse;
    55:       }
    56:       for (i=0; i<MagicNumber; i++)
    57:       {
    58:          cout << "\n(1)Bird (2)Pegasus: ";
    59:          cin >> choice;
    60:          if (choice == 2)
    61:             pBird = new Pegasus;
    62:          else
    63:             pBird = new Bird;
    64:          Aviary[i] = pBird;
    65:       }
    66:
    67:       cout << "\n";
    68:       for (i=0; i<MagicNumber; i++)
    69:       {
    70:          cout << "\nRanch[" << i << "]: " ;
    71:          Ranch[i]->Whinny();
    72:          delete Ranch[i];
    73:       }
    74:
    75:       for (i=0; i<MagicNumber; i++)
    76:       {
    77:          cout << "\nAviary[" << i << "]: " ;
    78:          Aviary[i]->Chirp();
    79:          Aviary[i]->Fly();
    80:          delete Aviary[i];
    81:       }
    82:     return 0;
    83: }

    Output: (1)Horse (2)Pegasus: 1
    Horse constructor...
    (1)Horse (2)Pegasus: 2
    Horse constructor... Bird constructor... Pegasus constructor...
    (1)Bird (2)Pegasus: 1
    Bird constructor...
    (1)Bird (2)Pegasus: 2
    Horse constructor... Bird constructor... Pegasus constructor...

    Ranch[0]: Whinny!... Horse destructor...
    Ranch[1]: Whinny!... Pegasus destructor...  Bird destructor... Horse destructor...
    Aviary[0]: Chirp... I can fly! I can fly! I can fly! Bird destructor...
    Aviary[1]: Whinny!... I can fly! I can fly! I can fly!
    Pegasus destructor... Bird destructor... Horse destructor...
    Aviary[0]: Chirp... I can fly!
    I can fly! I can fly! Bird destructor...
    Aviary[1]: Whinny!... I can fly! I can fly! I can fly!
    Pegasus destructor.. Bird destructor... Horse destructor...

Analysis: On lines 6-14, a `Horse` class is declared. The constructor and destructor print out a message, and the `Whinny()` method prints the word `Whinny!`

On lines 16-25, a `Bird` class is declared. In addition to its constructor and destructor, this class has two methods: `Chirp()` and `Fly()`, both of which print identifying messages. In a real program these might, for example, activate the speaker or generate animated images.

Finally, on lines 30-36, the class `Pegasus` is declared. It derives both from `Horse` and from `Bird`. The `Pegasus` class overrides the `Chirp()` method to call the `Whinny()` method, which it inherits from `Horse`.

Two lists are created, a `Ranch` with pointers to `Horse` on line 41, and an `Aviary` with pointers to `Bird` on line 42. On lines 46-55, `Horse` and `Pegasus` objects are added to the `Ranch`. On lines 56-65, `Bird` and `Pegasus` objects are added to the `Aviary`.

Invocations of the virtual methods on both the `Bird` pointers and the `Horse` pointers do the right things for `Pegasus` objects. For example, on line 78 the members of the `Aviary` array are used to call `Chirp()` on the objects to which they point. The `Bird` class declares this to be a virtual method, so the right function is called for each object.

Note that each time a `Pegasus` object is created, the output reflects that both the `Bird` part and the `Horse` part of the `Pegasus` object is also created. When a `Pegasus` object is destroyed, the `Bird` and `Horse` parts are destroyed as well, thanks to the destructors being made virtual.

### Declaring Multiple Inheritance

Declare an object to inherit from more than one class by listing the base classes following the colon after the class name. Separate the base classes by commas. Example 1:

    class Pegasus : public Horse, public Bird

Example 2:

    class Schnoodle : public Schnauzer, public Poodle

#### The Parts of a Multiply Inherited Object

When the `Pegasus` object is created in memory, both of the base classes form part of the `Pegasus` object, as illustrated in Figure 13.1.
Figure 13.1. Multiply inherited objects.
A number of issues arise with objects with multiple base classes. For example, what happens if two base classes that happen to have the same name have virtual functions or data? How are multiple base class constructors initialized? What happens if multiple base classes both derive from the same class? The next sections will answer these questions, and explore how multiple inheritance can be put to work.

#### Constructors in Multiply Inherited Objects

If `Pegasus` derives from both `Horse` and `Bird`, and each of the base classes has constructors that take parameters, the `Pegasus` class initializes these constructors in turn. Listing 13.4 illustrates how this is done.

Listing 13.4. Calling multiple constructors.

    1:     // Listing 13.4
    2:     // Calling multiple constructors
    3:     #include <iostream.h>
    4:     typedef int HANDS;
    5:     enum COLOR { Red, Green, Blue, Yellow, White, Black, Brown } ;
    6:     enum BOOL { FALSE, TRUE };
    7:
    8:     class Horse
    9:     {
    10:    public:
    11:       Horse(COLOR color, HANDS height);
    12:       virtual ~Horse() { cout << "Horse destructor...\n"; }
    13:       virtual void Whinny()const { cout << "Whinny!... "; }
    14:       virtual HANDS GetHeight() const { return itsHeight; }
    15:       virtual COLOR GetColor() const { return itsColor; }
    16:    private:
    17:       HANDS itsHeight;
    18:       COLOR itsColor;
    19:    };
    20:
    21:    Horse::Horse(COLOR color, HANDS height):
    22:       itsColor(color),itsHeight(height)
    23:    {
    24:       cout << "Horse constructor...\n";
    25:    }
    26:
    27:    class Bird
    28:    {
    29:    public:
    30:       Bird(COLOR color, BOOL migrates);
    31:       virtual ~Bird() {cout << "Bird destructor...\n";  }
    32:       virtual void Chirp()const { cout << "Chirp... ";  }
    33:       virtual void Fly()const
    34:       {
    35:          cout << "I can fly! I can fly! I can fly! ";
    36:       }
    37:       virtual COLOR GetColor()const { return itsColor; }
    38:       virtual BOOL GetMigration() const { return itsMigration; }
    39:
    40:    private:
    41:       COLOR itsColor;
    42:       BOOL itsMigration;
    43:    };
    44:
    45:    Bird::Bird(COLOR color, BOOL migrates):
    46:       itsColor(color), itsMigration(migrates)
    47:    {
    48:       cout << "Bird constructor...\n";
    49:    }
    50:
    51:    class Pegasus : public Horse, public Bird
    52:    {
    53:    public:
    54:       void Chirp()const { Whinny(); }
    55:       Pegasus(COLOR, HANDS, BOOL,long);
    56:       ~Pegasus() {cout << "Pegasus destructor...\n";}
    57:       virtual long GetNumberBelievers() const
    58:        {
    59:           return  itsNumberBelievers;
    60:        }
    61:
    62:    private:
    63:       long itsNumberBelievers;
    64:    };
    65:
    66:    Pegasus::Pegasus(
    67:        COLOR aColor,
    68:        HANDS height,
    69:        BOOL migrates,
    70:        long NumBelieve):
    71:    Horse(aColor, height),
    72:    Bird(aColor, migrates),
    73:    itsNumberBelievers(NumBelieve)
    74:    {
    75:       cout << "Pegasus constructor...\n";
    76:    }
    77:
    78:    int main()
    79:    {
    80:       Pegasus *pPeg = new Pegasus(Red, 5, TRUE, 10);
    81:       pPeg->Fly();
    82:       pPeg->Whinny();
    83:       cout << "\nYour Pegasus is " << pPeg->GetHeight();
    84:       cout << " hands tall and ";
    85:       if (pPeg->GetMigration())
    86:          cout << "it does migrate.";
    87:       else
    88:          cout << "it does not migrate.";
    89:       cout << "\nA total of " << pPeg->GetNumberBelievers();
    90:       cout << " people believe it exists.\n";
    91:       delete pPeg;
    92:     return 0;
    93: }

    Output: Horse constructor...
    Bird constructor...
    Pegasus constructor...
    I can fly! I can fly! I can fly! Whinny!...
    Your Pegasus is 5 hands tall and it does migrate.
    A total of 10 people believe it exists.
    Pegasus destructor...
    Bird destructor...
    Horse destructor...

Analysis: On lines 8-19, the `Horse` class is declared. The constructor takes two parameters, both using enumerations declared on lines 5 and 6. The implementation of the constructor on lines 21-25 simply initializes the member variables and prints a message.

On lines 27-43, the `Bird` class is declared, and the implementation of its constructor is on lines 45-49. Again, the `Bird` class takes two parameters. Interestingly, the `Horse` constructor takes color (so that you can detect horses of different colors), and the `Bird` constructor takes the color of the feathers (so those of one feather can stick together). This leads to a problem when you want to ask the `Pegasus` for its color, which you'll see in the next example.

The `Pegasus` class itself is declared on lines 51-64, and its constructor is on lines 66-72. The initialization of the `Pegasus` object includes three statements. First, the `Horse` constructor is initialized with color and height. Then the `Bird` constructor is initialized with color and the Boolean. Finally, the `Pegasus` member variable `itsNumberBelievers` is initialized. Once all that is accomplished, the body of the `Pegasus` constructor is called.

In the `main()` function, a `Pegasus` pointer is created and used to access the member functions of the base objects.

#### Ambiguity Resolution

In Listing 13.4, both the `Horse` class and the `Bird` class have a method `GetColor()`. You may need to ask the `Pegasus` object to return its color, but you have a problem: the `Pegasus` class inherits from both `Bird` and `Horse`. They both have a color, and their methods for getting that color have the same names and signature. This creates an ambiguity for the compiler, which you must resolve.

If you simply write

    COLOR currentColor = pPeg->GetColor();

you will get a compiler error:

    Member is ambiguous: `Horse::GetColor' and `Bird::GetColor'

You can resolve the ambiguity with an explicit call to the function you wish to invoke:

    COLOR currentColor = pPeg->Horse::GetColor();

Anytime you need to resolve which class a member function or member data inherits from, you can fully qualify the call by prepending the class name to the base class data or function.

Note that if `Pegasus` were to override this function, the problem would be moved, as it should be, into the `Pegasus` member function:

    virtual COLOR GetColor()const { return Horse::itsColor; }

This hides the problem from clients of the `Pegasus` class, and encapsulates within `Pegasus` the knowledge of which base class it wishes to inherit its color from. A client is still free to force the issue by writing:

    COLOR currentColor = pPeg->Bird::GetColor();

#### Inheriting from Shared Base Class

What happens if both `Bird` and `Horse` inherit from a common base class, such as `Animal`? Figure 13.2 illustrates what this looks like.

As you can see in Figure 13.2, two base class objects exist. When a function or data member is called in the shared base class, another ambiguity exists. For example, if `Animal` declares `itsAge` as a member variable and `GetAge()` as a member function, and you call `pPeg->GetAge()`, did you mean to call the `GetAge()` function you inherit from `Animal` by way of `Horse`, or by way of `Bird`? You must resolve this ambiguity as well, as illustrated in Listing 13.5.
Figure 13.2. Common base classes.

Listing 13.5. Common base classes.

    1:     // Listing 13.5
    2:     // Common base classes
    3:     #include <iostream.h>
    4:
    5:     typedef int HANDS;
    6:     enum COLOR { Red, Green, Blue, Yellow, White, Black, Brown } ;
    7:     enum BOOL { FALSE, TRUE };
    8:
    9:     class Animal        // common base to both horse and bird
    10:    {
    11:    public:
    12:       Animal(int);
    13:       virtual ~Animal() { cout << "Animal destructor...\n"; }
    14:       virtual int GetAge() const { return itsAge; }
    15:       virtual void SetAge(int age) { itsAge = age; }
    16:    private:
    17:       int itsAge;
    18:    };
    19:
    20:    Animal::Animal(int age):
    21:    itsAge(age)
    22:    {
    23:       cout << "Animal constructor...\n";
    24:    }
    25:
    26:    class Horse : public Animal
    27:    {
    28:    public:
    29:       Horse(COLOR color, HANDS height, int age);
    30:       virtual ~Horse() { cout << "Horse destructor...\n"; }
    31:       virtual void Whinny()const { cout << "Whinny!... "; }
    32:       virtual HANDS GetHeight() const { return itsHeight; }
    33:       virtual COLOR GetColor() const { return itsColor; }
    34:    protected:
    35:       HANDS itsHeight;
    36:       COLOR itsColor;
    37:    };
    38:
    39:    Horse::Horse(COLOR color, HANDS height, int age):
    40:       Animal(age),
    41:       itsColor(color),itsHeight(height)
    42:    {
    43:       cout << "Horse constructor...\n";
    44:    }
    45:
    46:    class Bird : public Animal
    47:    {
    48:    public:
    49:       Bird(COLOR color, BOOL migrates, int age);
    50:       virtual ~Bird() {cout << "Bird destructor...\n";  }
    51:       virtual void Chirp()const { cout << "Chirp... ";  }
    52:       virtual void Fly()const
    53:           { cout << "I can fly! I can fly! I can fly! "; }
    54:       virtual COLOR GetColor()const { return itsColor; }
    55:       virtual BOOL GetMigration() const { return itsMigration; }
    56:    protected:
    57:       COLOR itsColor;
    58:       BOOL itsMigration;
    59:    };
    60:
    61:    Bird::Bird(COLOR color, BOOL migrates, int age):
    62:       Animal(age),
    63:       itsColor(color), itsMigration(migrates)
    64:    {
    65:       cout << "Bird constructor...\n";
    66:    }
    67:
    68:    class Pegasus : public Horse, public Bird
    69:    {
    70:    public:
    71:       void Chirp()const { Whinny(); }
    72:       Pegasus(COLOR, HANDS, BOOL, long, int);
    73:       ~Pegasus() {cout << "Pegasus destructor...\n";}
    74:       virtual long GetNumberBelievers() const
    75:          { return  itsNumberBelievers; }
    76:       virtual COLOR GetColor()const { return Horse::itsColor; }
    77:       virtual int GetAge() const { return Horse::GetAge(); }
    78:    private:
    79:       long itsNumberBelievers;
    80:    };
    81:
    82:    Pegasus::Pegasus(
    83:       COLOR aColor,
    84:       HANDS height,
    85:       BOOL migrates,
    86:       long NumBelieve,
    87:       int age):
    88:    Horse(aColor, height,age),
    89:    Bird(aColor, migrates,age),
    90:    itsNumberBelievers(NumBelieve)
    91:    {
    92:       cout << "Pegasus constructor...\n";
    93:    }
    94:
    95:    int main()
    96:    {
    97:       Pegasus *pPeg = new Pegasus(Red, 5, TRUE, 10, 2);
    98:       int age = pPeg->GetAge();
    99:       cout << "This pegasus is " << age << " years old.\n";
    100:      delete pPeg;
    101:     return 0;
    102: }

    Output: Animal constructor...
    Horse constructor...
    Animal constructor...
    Bird constructor...
    Pegasus constructor...
    This pegasus is 2 years old.
    Pegasus destructor...
    Bird destructor...
    Animal destructor...
    Horse destructor...
    Animal destructor...

Analysis: There are a number of interesting features to this listing. The `Animal` class is declared on lines 9-18. `Animal` adds one member variable, `itsAge` and an accessor, `SetAge()`.

On line 26, the `Horse` class is declared to derive from `Animal`. The `Horse` constructor now has a third parameter, `age`, which it passes to its base class, `Animal`. Note that the `Horse` class does not override `GetAge()`, it simply inherits it.

On line 46, the `Bird` class is declared to derive from `Animal`. Its constructor also takes an age and uses it to initialize its base class, `Animal`. It also inherits `GetAge()` without overriding it.

`Pegasus` inherits from both `Bird` and from `Animal`, and so has two `Animal` classes in its inheritance chain. If you were to call `GetAge()` on a `Pegasus` object, you would have to disambiguate, or fully qualify, the method you want if `Pegasus` did not override the method.

This is solved on line 76 when the `Pegasus` object overrides `GetAge()` to do nothing more than to chain up--that is, to call the same method in a base class.

Chaining up is done for two reasons: either to disambiguate which base class to call, as in this case, or to do some work and then let the function in the base class do some more work. At times, you may want to do work and then chain up, or chain up and then do the work when the base class function returns.

The `Pegasus` constructor takes five parameters: the creature's color, its height (in `HANDS`), whether or not it migrates, how many believe in it, and its age. The constructor initializes the `Horse` part of the `Pegasus` with the color, height, and age on line 88. It initializes the `Bird` part with color, whether it migrates, and age on line 89. Finally, it initializes `itsNumberBelievers` on line 90.

The call to the `Horse` constructor on line 88 invokes the implementation shown on line 39. The `Horse` constructor uses the `age` parameter to initialize the `Animal` part of the `Horse` part of the `Pegasus`. It then goes on to initialize the two member variables of `Horse`--`itsColor` and `itsAge`.

The call to the `Bird` constructor on line 89 invokes the implementation shown on line 46. Here too, the `age` parameter is used to initialize the `Animal` part of the `Bird`.

Note that the `color` parameter to the `Pegasus` is used to initialize member variables in each of `Bird` and `Horse`. Note also that the `age` is used to initialize `itsAge` in the `Horse`'s base `Animal` and in the `Bird`'s base `Animal`.

#### Virtual Inheritance

In Listing 13.5, the `Pegasus` class went to some lengths to disambiguate which of its `Animal` base classes it meant to invoke. Most of the time, the decision as to which one to use is arbitrary--after all, the `Horse` and the `Bird` have exactly the same base class.

It is possible to tell C++ that you do not want two copies of the shared base class, as shown in Figure 13.2, but rather to have a single shared base class, as shown in Figure 13.3.

You accomplish this by making `Animal` a virtual base class of both `Horse` and `Bird`. The `Animal` class does not change at all. The `Horse` and `Bird` classes change only in their use of the term virtual in their declarations. `Pegasus`, however, changes substantially.

Normally, a class's constructor initializes only its own variables and its base class. Virtually inherited base classes are an exception, however. They are initialized by their most derived class. Thus, `Animal` is initialized not by `Horse` and `Bird`, but by `Pegasus`. `Horse` and `Bird` have to initialize `Animal` in their constructors, but these initializations will be ignored when a `Pegasus` object is created.

Listing 13.6 rewrites Listing 13.5 to take advantage of virtual derivation.
Figure 13.3. A diamond inheritance.

Listing 13.6. Illustration of the use of virtual inheritance.

    1:     // Listing 13.6
    2:     // Virtual inheritance
    3:     #include <iostream.h>
    4:
    5:     typedef int HANDS;
    6:     enum COLOR { Red, Green, Blue, Yellow, White, Black, Brown } ;
    7:     enum BOOL { FALSE, TRUE };
    8:
    9:     class Animal        // common base to both horse and bird
    10:    {
    11:    public:
    12:       Animal(int);
    13:       virtual ~Animal() { cout << "Animal destructor...\n"; }
    14:       virtual int GetAge() const { return itsAge; }
    15:       virtual void SetAge(int age) { itsAge = age; }
    16:    private:
    17:       int itsAge;
    18:    };
    19:
    20:    Animal::Animal(int age):
    21:    itsAge(age)
    22:    {
    23:       cout << "Animal constructor...\n";
    24:    }
    25:
    26:    class Horse : virtual public Animal
    27:    {
    28:    public:
    29:       Horse(COLOR color, HANDS height, int age);
    30:       virtual ~Horse() { cout << "Horse destructor...\n"; }
    31:       virtual void Whinny()const { cout << "Whinny!... "; }
    32:       virtual HANDS GetHeight() const { return itsHeight; }
    33:       virtual COLOR GetColor() const { return itsColor; }
    34:    protected:
    35:       HANDS itsHeight;
    36:       COLOR itsColor;
    37:    };
    38:
    39:    Horse::Horse(COLOR color, HANDS height, int age):
    40:       Animal(age),
    41:       itsColor(color),itsHeight(height)
    42:    {
    43:       cout << "Horse constructor...\n";
    44:    }
    45:
    46:    class Bird : virtual public Animal
    47:    {
    48:    public:
    49:       Bird(COLOR color, BOOL migrates, int age);
    50:       virtual ~Bird() {cout << "Bird destructor...\n";  }
    51:       virtual void Chirp()const { cout << "Chirp... ";  }
    52:       virtual void Fly()const
    53:          { cout << "I can fly! I can fly! I can fly! "; }
    54:       virtual COLOR GetColor()const { return itsColor; }
    55:       virtual BOOL GetMigration() const { return itsMigration; }
    56:    protected:
    57:       COLOR itsColor;
    58:       BOOL itsMigration;
    59:    };
    60:
    61:    Bird::Bird(COLOR color, BOOL migrates, int age):
    62:       Animal(age),
    63:       itsColor(color), itsMigration(migrates)
    64:    {
    65:       cout << "Bird constructor...\n";
    66:    }
    67:
    68:    class Pegasus : public Horse, public Bird
    69:    {
    70:    public:
    71:       void Chirp()const { Whinny(); }
    72:       Pegasus(COLOR, HANDS, BOOL, long, int);
    73:       ~Pegasus() {cout << "Pegasus destructor...\n";}
    74:       virtual long GetNumberBelievers() const
    75:          { return  itsNumberBelievers; }
    76:       virtual COLOR GetColor()const { return Horse::itsColor; }
    77:    private:
    78:       long itsNumberBelievers;
    79:    };
    80:
    81:    Pegasus::Pegasus(
    82:       COLOR aColor,
    83:       HANDS height,
    84:       BOOL migrates,
    85:       long NumBelieve,
    86:       int age):
    87:    Horse(aColor, height,age),
    88:    Bird(aColor, migrates,age),
    89:    Animal(age*2),
    90:    itsNumberBelievers(NumBelieve)
    91:    {
    92:       cout << "Pegasus constructor...\n";
    93:    }
    94:
    95:    int main()
    96:    {
    97:       Pegasus *pPeg = new Pegasus(Red, 5, TRUE, 10, 2);
    98:       int age = pPeg->GetAge();
    99:       cout << "This pegasus is " << age << " years old.\n";
    100:      delete pPeg;
    101:     return 0;
    102: }

    Output: Animal constructor...
    Horse constructor...
    Bird constructor...
    Pegasus constructor...
    This pegasus is 4 years old.
    Pegasus destructor...
    Bird destructor...
    Horse destructor...
    Animal destructor...

Analysis: On line 26, `Horse` declares that it inherits virtually from `Animal`, and on line 46, `Bird` makes the same declaration. Note that the constructors for both `Bird` and `Animal` still initialize the `Animal` object.

`Pegasus` inherits from both `Bird` and `Animal`, and as the most derived object of `Animal`, it also initializes `Animal`. It is `Pegasus`' initialization which is called, however, and the calls to `Animal`'s constructor in `Bird` and `Horse` are ignored. You can see this because the value `2` is passed in, and `Horse` and `Bird` pass it along to `Animal`, but `Pegasus` doubles it. The result, 4, is reflected in the printout on line 99 and as shown in the output.

`Pegasus` no longer has to disambiguate the call to `GetAge()`, and so is free to simply inherit this function from `Animal`. Note that `Pegasus` must still disambiguate the call to `GetColor()`, as this function is in both of its base classes and not in `Animal`.

### Declaring Classes for Virtual Inheritance

To ensure that derived classes have only one instance of common base classes, declare the intermediate classes to inherit virtually from the base class. Example 1:

    class Horse : virtual public Animal
    class Bird : virtual public Animal
    class Pegasus : public Horse, public Bird

Example 2:

    class Schnauzer : virtual public Dog
    class Poodle : virtual public Dog

    class Schnoodle : public Schnauzer, public Poodle

#### Problems with Multiple Inheritance

Although multiple inheritance offers a number of advantages over single inheritance, there are many C++ programmers who are reluctant to use it. The problems they cite are that many compilers don't support it yet, that it makes debugging harder, and that nearly everything that can be done with multiple inheritance can be done without it.

These are valid concerns, and you will want to be on your guard against installing needless complexity into your programs. Some debuggers have a hard time with multiple inheritance, and some designs are needlessly made complex by using multiple inheritance when it is not needed.

> DO use multiple inheritance when a new class needs functions and features from more than one base class. DO use virtual inheritance when the most derived classes must have only one instance of the shared base class. DO initialize the shared base class from the most derived class when using virtual base classes. DON'T use multiple inheritance when single inheritance will do.

#### Mixins and Capabilities Classes

One way to strike a middle ground between multiple inheritance and single inheritance is to use what are called mixins. Thus, you might have your `Horse` class derive from `Animal` and from `Displayable`. `Displayable` would just add a few methods for displaying any object onscreen.

  New Term: A mixin , or capability class, is a class that adds functionality without adding much or any data.

Capability classes are mixed into a derived class like any other class might be, by declaring the derived class to inherit publicly from them. The only difference between a capability class and any other class is that the capability class has little or no data. This is an arbitrary distinction, of course, and is just a shorthand way of noting that at times all you want to do is mix in some additional capabilities without complicating the derived class.

This will, for some debuggers, make it easier to work with mixins than with more complex multiply inherited objects. There is also less likelihood of ambiguity in accessing the data in the other principal base class.

For example, if `Horse` derives from `Animal` and from `Displayable`, `Displayable` would have no data. `Animal` would be just as it always was, so all the data in `Horse` would derive from `Animal`, but the functions in `Horse` would derive from both.

The term mixin comes from an ice-cream store in Sommerville, Massachusetts, where candies and cakes were mixed into the basic ice-cream flavors. This seemed like a good metaphor to some of the object-oriented programmers who used to take a summer break there, especially while working with the object-oriented programming language SCOOPS.

### Abstract Data Types

Often, you will create a hierarchy of classes together. For example, you might create a `Shape` class, and derive from that `Rectangle` and `Circle`. From `Rectangle`, you might derive `Square`, as a special case of `Rectangle`.

Each of the derived classes will override the `Draw()` method, the `GetArea()` method, and so forth. Listing 13.7 illustrates a bare-bones implementation of the `Shape` class and its derived `Circle` and `Rectangle` classes.

Listing 13.7. Shape classes.

    1:     //Listing 13.7. Shape classes.
    2:
    3:     #include <iostream.h>
    4:
    5:     enum BOOL { FALSE, TRUE };
    6:
    7:     class Shape
    8:     {
    9:     public:
    10:       Shape(){}
    11:       ~Shape(){}
    12:       virtual long GetArea() { return -1; } // error
    13:       virtual long GetPerim() { return -1; }
    14:       virtual void Draw() {}
    15:    private:
    16:    };
    17:
    18:    class Circle : public Shape
    19:    {
    20:    public:
    21:          Circle(int radius):itsRadius(radius){}
    22:          ~Circle(){}
    23:          long GetArea() { return 3 * itsRadius * itsRadius; }
    24:          long GetPerim() { return 9 * itsRadius; }
    25:          void Draw();
    26:    private:
    27:       int itsRadius;
    28:       int itsCircumference;
    29:    };
    30:
    31:    void Circle::Draw()
    32:    {
    33:       cout << "Circle drawing routine here!\n";
    34:    }
    35:
    36:
    37:    class Rectangle : public Shape
    38:    {
    39:    public:
    40:          Rectangle(int len, int width):
    41:             itsLength(len), itsWidth(width){}
    42:          ~Rectangle(){}
    43:          virtual long GetArea() { return itsLength * itsWidth; }
    44:          virtual long GetPerim() {return 2*itsLength + 2*itsWidth; }
    45:          virtual int GetLength() { return itsLength; }
    46:          virtual int GetWidth() { return itsWidth; }
    47:          virtual void Draw();
    48:    private:
    49:       int itsWidth;
    50:       int itsLength;
    51:    };
    52:
    53:    void Rectangle::Draw()
    54:    {
    55:       for (int i = 0; i<itsLength; i++)
    56:       {
    57:          for (int j = 0; j<itsWidth; j++)
    58:             cout << "x ";
    59:
    60:          cout << "\n";
    61:       }
    62:    }
    63:
    64:    class Square : public Rectangle
    65:    {
    66:    public:
    67:          Square(int len);
    68:          Square(int len, int width);
    69:          ~Square(){}
    70:          long GetPerim() {return 4 * GetLength();}
    71:    };
    72:
    73:    Square::Square(int len):
    74:       Rectangle(len,len)
    75:    {}
    76:
    77:    Square::Square(int len, int width):
    78:       Rectangle(len,width)
    79:
    80:    {
    81:       if (GetLength() != GetWidth())
    82:          cout << "Error, not a square... a Rectangle??\n";
    83:    }
    84:
    85:    int main()
    86:    {
    87:       int choice;
    88:       BOOL fQuit = FALSE;
    89:       Shape * sp;
    90:
    91:       while (1)
    92:       {
    93:          cout << "(1)Circle (2)Rectangle (3)Square (0)Quit: ";
    94:          cin >> choice;
    95:
    96:          switch (choice)
    97:          {
    98:             case 1: sp = new Circle(5);
    99:             break;
    100:            case 2: sp = new Rectangle(4,6);
    101:            break;
    102:            case 3: sp = new Square(5);
    103:            break;
    104:            default: fQuit = TRUE;
    105:            break;
    106:         }
    107:         if (fQuit)
    108:            break;
    109:
    110:         sp->Draw();
    111:         cout << "\n";
    112:      }
    113:     return 0;
    114: }

    Output: (1)Circle (2)Rectangle (3)Square (0)Quit: 2
    x x x x x x
    x x x x x x
    x x x x x x
    x x x x x x

    (1)Circle (2)Rectangle (3)Square (0)Quit:3
    x x x x x
    x x x x x
    x x x x x
    x x x x x
    x x x x x

    (1)Circle (2)Rectangle (3)Square (0)Quit:0

Analysis: On lines 7-16, the `Shape` class is declared. The `GetArea()` and `GetPerim()` methods return an error value, and `Draw()` takes no action. After all, what does it mean to draw a Shape? Only types of shapes (circles, rectangle, and so on) can be drawn, `Shapes` as an abstraction cannot be drawn.

`Circle` derives from `Shape` and overrides the three virtual methods. Note that there is no reason to add the word "virtual," as that is part of their inheritance. But there is no harm in doing so either, as shown in the `Rectangle` class on lines 43, 44, and 47. It is a good idea to include the term virtual as a reminder, a form of documentation.

`Square` derives from `Rectangle`, and it too overrides the `GetPerim()` method, inheriting the rest of the methods defined in `Rectangle`.

It is troubling, though, that a client might try to instantiate a `Shape` object, and it might be desirable to make that impossible. The `Shape` class exists only to provide an interface for the classes derived from it; as such it is an Abstract Data Type, or ADT.

  New Term: An Abstract Data Type represents a concept (like shape) rather than an object (like circle). In C++, an ADT is always the base class to other classes, and it is not valid to make an instance of an ADT.

#### Pure Virtual Functions

C++ supports the creation of abstract data types with pure virtual functions. A virtual function ismade pure by initializing it with zero, as in

    virtual void Draw() = 0;

Any class with one or more pure virtual functions is an ADT, and it is illegal to instantiate an object of a class that is an ADT. Trying to do so will cause a compile-time error. Putting a pure virtual function in your class signals two things to clients of your class:

- Don't make an object of this class, derive from it.

- Make sure you override the pure virtual function.

Any class that derives from an ADT inherits the pure virtual function as pure, and so must override every pure virtual function if it wants to instantiate objects. Thus, if `Rectangle` inherits from `Shape`, and `Shape` has three pure virtual functions, `Rectangle` must override all three or it too will be an ADT. Listing 13.8 rewrites the `Shape` class to be an abstract data type. To save space, the rest of Listing 13.7 is not reproduced here. Replace the declaration of `Shape` in Listing 13.7, lines 7-16, with the declaration of `Shape` in Listing 13.8 and run the program again.

Listing 13.8. Abstract Data Types.

    1:  class Shape
    2:  {
    3:  public:
    4:       Shape(){}
    5:       ~Shape(){}
    6:       virtual long GetArea() = 0; // error
    7:       virtual long GetPerim()= 0;
    8:       virtual void Draw() = 0;
    9:  private:

`10: };`

    Output: (1)Circle (2)Rectangle (3)Square (0)Quit: 2
    x x x x x x
    x x x x x x
    x x x x x x
    x x x x x x

    (1)Circle (2)Rectangle (3)Square (0)Quit: 3
    x x x x x
    x x x x x
    x x x x x
    x x x x x
    x x x x x

    (1)Circle (2)Rectangle (3)Square (0)Quit: 0

Analysis: As you can see, the workings of the program are totally unaffected. The only difference is that it would now be impossible to make an object of class `Shape`.

### Abstract Data Types

Declare a class to be an abstract data type by including one or more pure virtual functions in the class declaration. Declare a pure virtual function by writing `= 0` after the function declaration. Example:

    class Shape
    {
    virtual void Draw() = 0;    // pure virtual
    };

#### Implementing Pure Virtual Functions

Typically, the pure virtual functions in an abstract base class are never implemented. Because no objects of that type are ever created, there is no reason to provide implementations, and the ADT works purely as the definition of an interface to objects which derive from it.

It is possible, however, to provide an implementation to a pure virtual function. The function can then be called by objects derived from the ADT, perhaps to provide common functionality to all the overridden functions. Listing 13.9 reproduces Listing 13.7, this time with `Shape` as an ADT and with an implementation for the pure virtual function `Draw()`. The `Circle` class overrides `Draw()`, as it must, but it then chains up to the base class function for additional functionality.

In this example, the additional functionality is simply an additional message printed, but one can imagine that the base class provides a shared drawing mechanism, perhaps setting up a window that all derived classes will use.

Listing 13.9. Implementing pure virtual functions.

    1:     //Implementing pure virtual functions
    2:
    3:     #include <iostream.h>
    4:
    5:     enum BOOL { FALSE, TRUE };
    6:
    7:     class Shape
    8:     {
    9:     public:
    10:       Shape(){}
    11:       ~Shape(){}
    12:       virtual long GetArea() = 0; // error
    13:       virtual long GetPerim()= 0;
    14:       virtual void Draw() = 0;
    15:    private:
    16:    };
    17:
    18:     void Shape::Draw()
    19:    {
    20:       cout << "Abstract drawing mechanism!\n";
    21:    }
    22:
    23:    class Circle : public Shape
    24:    {
    25:    public:
    26:          Circle(int radius):itsRadius(radius){}
    27:          ~Circle(){}
    28:          long GetArea() { return 3 * itsRadius * itsRadius; }
    29:          long GetPerim() { return 9 * itsRadius; }
    30:          void Draw();
    31:    private:
    32:       int itsRadius;
    33:       int itsCircumference;
    34:    };
    35:
    36:    void Circle::Draw()
    37:    {
    38:       cout << "Circle drawing routine here!\n";
    39:       Shape::Draw();
    40:    }
    41:
    42:
    43:    class Rectangle : public Shape
    44:    {
    45:    public:
    46:          Rectangle(int len, int width):
    47:             itsLength(len), itsWidth(width){}
    48:          ~Rectangle(){}
    49:          long GetArea() { return itsLength * itsWidth; }
    50:          long GetPerim() {return 2*itsLength + 2*itsWidth; }
    51:          virtual int GetLength() { return itsLength; }
    52:          virtual int GetWidth() { return itsWidth; }
    53:          void Draw();
    54:    private:
    55:       int itsWidth;
    56:       int itsLength;
    57:    };
    58:
    59:    void Rectangle::Draw()
    60:    {
    61:       for (int i = 0; i<itsLength; i++)
    62:       {
    63:          for (int j = 0; j<itsWidth; j++)
    64:             cout << "x ";
    65:
    66:          cout << "\n";
    67:       }
    68:       Shape::Draw();
    69:    }
    70:
    71:
    72:    class Square : public Rectangle
    73:    {
    74:    public:
    75:          Square(int len);
    76:          Square(int len, int width);
    77:          ~Square(){}
    78:          long GetPerim() {return 4 * GetLength();}
    79:    };
    80:
    81:    Square::Square(int len):
    82:       Rectangle(len,len)
    83:    {}
    84:
    85:    Square::Square(int len, int width):
    86:       Rectangle(len,width)
    87:
    88:    {
    89:       if (GetLength() != GetWidth())
    90:          cout << "Error, not a square... a Rectangle??\n";
    91:    }
    92:
    93:    int main()
    94:    {
    95:       int choice;
    96:       BOOL fQuit = FALSE;
    97:       Shape * sp;
    98:
    99:       while (1)
    100:      {
    101:         cout << "(1)Circle (2)Rectangle (3)Square (0)Quit: ";
    102:         cin >> choice;
    103:
    104:         switch (choice)
    105:         {
    106:            case 1: sp = new Circle(5);
    107:            break;
    108:            case 2: sp = new Rectangle(4,6);
    109:            break;
    110:            case 3: sp = new Square (5);
    111:            break;
    112:            default: fQuit = TRUE;
    113:            break;
    114:         }
    115:         if (fQuit)
    116:            break;
    117:
    118:         sp->Draw();
    119:         cout << "\n";
    120:      }
    121:     return 0;
    122: }

    Output: (1)Circle (2)Rectangle (3)Square (0)Quit: 2
    x x x x x x
    x x x x x x
    x x x x x x
    x x x x x x
    Abstract drawing mechanism!

    (1)Circle (2)Rectangle (3)Square (0)Quit: 3
    x x x x x
    x x x x x
    x x x x x
    x x x x x
    x x x x x
    Abstract drawing mechanism!

    (1)Circle (2)Rectangle (3)Square (0)Quit: 0

Analysis: On lines 7-16, the abstract data type `Shape` is declared, with all three of its accessor methods declared to be pure virtual. Note that this is not necessary. If any one were declared pure virtual, the class would have been an ADT.

The `GetArea()` and `GetPerim()` methods are not implemented, but `Draw()` is. `Circle` and `Rectangle` both override `Draw()`, and both chain up to the base method, taking advantage of shared functionality in the base class.

#### Complex Hierarchies of Abstraction

At times, you will derive ADTs from other ADTs. It may be that you will want to make some of the derived pure virtual functions non-pure, and leave others pure.

If you create the `Animal` class, you may make `Eat()`,`Sleep()`,`Move()`, and `Reproduce()` all be pure virtual functions. Perhaps from `Animal` you derive `Mammal` and `Fish`.

On examination, you decide that every `Mammal` will reproduce in the same way, and so you make `Mammal::Reproduce()` be non-pure, but you leave `Eat()`,`Sleep()`, and `Move()` as pure virtual functions.

From `Mammal` you derive `Dog`, and `Dog` must override and implement the three remaining pure virtual functions so that you can make objects of type `Dog`.

What you've said, as class designer, is that no `Animal`s or `Mammal`s can be instantiated, but that all `Mammal`s may inherit the provided `Reproduce()` method without overriding it.

Listing 13.10 illustrates this technique with a bare-bones implementation of these classes.

Listing 13.10. Deriving ADTs from other ADTs.

    1:     // Listing 13.10
    2:     // Deriving ADTs from other ADTs
    3:     #include <iostream.h>
    4:
    5:     enum COLOR { Red, Green, Blue, Yellow, White, Black, Brown } ;
    6:     enum BOOL { FALSE, TRUE };
    7:
    8:     class Animal        // common base to both horse and bird
    9:     {
    10:    public:
    11:       Animal(int);
    12:       virtual ~Animal() { cout << "Animal destructor...\n"; }
    13:       virtual int GetAge() const { return itsAge; }
    14:       virtual void SetAge(int age) { itsAge = age; }
    15:       virtual void Sleep() const = 0;
    16:       virtual void Eat() const = 0;
    17:       virtual void Reproduce() const = 0;
    18:       virtual void Move() const = 0;
    19:       virtual void Speak() const = 0;
    20:    private:
    21:       int itsAge;
    22:    };
    23:
    24:    Animal::Animal(int age):
    25:    itsAge(age)
    26:    {
    27:       cout << "Animal constructor...\n";
    28:    }
    29:
    30:    class Mammal : public Animal
    31:    {
    32:    public:
    33:       Mammal(int age):Animal(age)
    34:          { cout << "Mammal constructor...\n";}
    35:       ~Mammal() { cout << "Mammal destructor...\n";}
    36:       virtual void Reproduce() const
    37:           { cout << "Mammal reproduction depicted...\n"; }
    38:    };
    39:
    40:    class Fish : public Animal
    41:    {
    42:    public:
    43:       Fish(int age):Animal(age)
    44:          { cout << "Fish constructor...\n";}
    45:       virtual ~Fish() {cout << "Fish destructor...\n";  }
    46:       virtual void Sleep() const { cout << "fish snoring...\n"; }
    47:       virtual void Eat() const { cout << "fish feeding...\n"; }
    48:       virtual void Reproduce() const
    49:          { cout << "fish laying eggs...\n"; }
    50:       virtual void Move() const
    51:           { cout << "fish swimming...\n";   }
    52:       virtual void Speak() const { }
    53:    };
    54:
    55:    class Horse : public Mammal
    56:    {
    57:    public:
    58:       Horse(int age, COLOR color ):
    59:       Mammal(age), itsColor(color)
    60:             { cout << "Horse constructor...\n"; }
    61:       virtual ~Horse() { cout << "Horse destructor...\n"; }
    62:       virtual void Speak()const { cout << "Whinny!... \n"; }
    63:       virtual COLOR GetItsColor() const { return itsColor; }
    64:       virtual void Sleep() const
    65:           { cout << "Horse snoring...\n"; }
    66:       virtual void Eat() const { cout << "Horse feeding...\n"; }
    67:       virtual void Move() const { cout << "Horse running...\n";}
    68:
    69:    protected:
    70:       COLOR itsColor;
    71:    };
    72:
    73:    class Dog : public Mammal
    74:    {
    75:    public:
    76:       Dog(int age, COLOR color ):
    77:          Mammal(age), itsColor(color)
    78:             { cout << "Dog constructor...\n"; }
    79:       virtual ~Dog() { cout << "Dog destructor...\n"; }
    80:       virtual void Speak()const { cout << "Whoof!... \n"; }
    81:       virtual void Sleep() const { cout << "Dog snoring...\n"; }
    82:       virtual void Eat() const { cout << "Dog eating...\n"; }
    83:       virtual void Move() const  { cout << "Dog running...\n"; }
    84:       virtual void Reproduce() const
    85:           { cout << "Dogs reproducing...\n"; }
    86:
    87:    protected:
    88:       COLOR itsColor;
    89:    };
    90:
    91:    int main()
    92:    {
    93:       Animal *pAnimal=0;
    94:       int choice;
    95:       BOOL fQuit = FALSE;
    96:
    97:       while (1)
    98:       {
    99:          cout << "(1)Dog (2)Horse (3)Fish (0)Quit: ";
    100:          cin >> choice;
    101:
    102:          switch (choice)
    103:          {
    104:             case 1: pAnimal = new Dog(5,Brown);
    105:             break;
    106:             case 2: pAnimal = new Horse(4,Black);
    107:             break;
    108:            case 3: pAnimal = new Fish (5);
    109:            break;
    110:            default: fQuit = TRUE;
    111:            break;
    112:         }
    113:         if (fQuit)
    114:            break;
    115:
    116:         pAnimal->Speak();
    117:         pAnimal->Eat();
    118:         pAnimal->Reproduce();
    119:         pAnimal->Move();
    120:         pAnimal->Sleep();
    121:         delete pAnimal;
    122:         cout << "\n";
    123:      }
    124:     return 0
    125: }

    Output: (1)Dog (2)Horse (3)Bird (0)Quit: 1
    Animal constructor...
    Mammal constructor...
    Dog constructor...
    Whoof!...
    Dog eating...
    Dog reproducing....
    Dog running...
    Dog snoring...
    Dog destructor...
    Mammal destructor...
    Animal destructor...

    (1)Dog (2)Horse (3)Bird (0)Quit: 0

Analysis: On lines 8-22, the abstract data type `Animal` is declared. `Animal` has non-pure virtual accessors for `itsAge`, which are shared by all `Animal` objects. It has five pure virtual functions, `Sleep()`,`Eat()`,`Reproduce()`,`Move()`, and `Speak()`.

`Mammal` is derived from `Animal`, is declared on lines 30-38, and adds no data. It overrides `Reproduce()`, however, providing a common form of reproduction for all mammals. `Fish` must override `Reproduce()`, because `Fish` derives directly from `Animal` and cannot take advantage of Mammalian reproduction (and a good thing, too!).

`Mammal` classes no longer have to override the `Reproduce()` function, but they are free to do so if they choose, as `Dog` does on line 84. `Fish`, `Horse`, and `Dog` all override the remaining pure virtual functions, so that objects of their type can be instantiated.

In the body of the program, an `Animal` pointer is used to point to the various derived objects in turn. The virtual methods are invoked, and based on the runtime binding of the pointer, the correct method is called in the derived class.

It would be a compile-time error to try to instantiate an `Animal` or a `Mammal`, as both are abstract data types.

#### Which Types Are Abstract?

In one program, the class `Animal` is abstract, in another it is not. What determines whether to make a class abstract or not?

The answer to this question is decided not by any real-world intrinsic factor, but by what makes sense in your program. If you are writing a program that depicts a farm or a zoo, you may want `Animal` to be an abstract data type, but `Dog` to be a class from which you can instantiate objects.

On the other hand, if you are making an animated kennel, you may want to keep `Dog` as an abstract data type, and only instantiate types of dogs: retrievers, terriers, and so fort. The level of abstraction is a function of how finely you need to distinguish your types.

> DO use abstract data types to provide common functionality for a number of related classes. DO override all pure virtual functions. DO make pure virtual any function that must be overridden. DON'T try to instantiate an object of an abstract data type.

### The Observer Pattern

A very hot trend in C++ is the creation and dissemination of design patterns. These are well- documented solutions to common problems encountered by C++ programmers. As an example, the observer pattern solves a common problem in inheritance.

Imagine you develop a timer class which knows how to count elapsed seconds. Such a class might have a class member `itsSeconds` which is an integer, and it would have methods to set, get, and increment `itsSeconds`.

Now let's further assume that your program wants to be informed every time the timer's `itsSeconds` member is incremented. One obvious solution would be to put a notification method into the timer. However, notification is not an intrinsic part of timing, and the complex code for registering those classes which need to be informed when the clock increments doesn't really belong in your timer class.

More importantly, once you work out the logic of registering those who are interested in these changes, and then notifying them, you'd like to abstract this out into a class of its own and be able to reuse it with other classes which might be "observed" in this way.

Therefore, a better solution is to create an observer class. Make this observer an Abstract Data Type with a pure virtual function `Update()`.

Now create a second abstract data type, called `Subject`. `Subject` keeps an array of `Observer` objects and also provides two methods: `register()` (which adds observers to its list) and `Notify()`, which is called when there is something to report.

Those classes which wish to be notified of your timer's changes inherit from `Observer`. The timer itself inherits from `Subject`. The `Observer` class registers itself with the `Subject` class. The `Subject` class calls `Notify` when it changes (in this case when the timer updates).

Finally, we note that not every client of timer wants to be observable, and thus we create a new class called `ObservedTimer`, which inherits both from timer and from `Subject`. This gives the `ObservedTimer` the timer characteristics and the ability to be observed.

#### A Word About Multiple Inheritance, Abstract Data Types, and Java

Many C++ programmers are aware that Java was based in large part on C++, and yet the creators of Java chose to leave out multiple inheritance. It was their opinion that multiple inheritance introduced complexity that worked against the ease of use of Java. They felt they could meet 90% of the multiple inheritance functionality using what are called interfaces.

  New Term: An interface is much like an Abstract Data Type in that it defines a set of functions that can only be implemented in a derived class. However, with interfaces, you don't directly derive from the interface, you derive from another class and implement the interface, much like multiple inheritance. Thus, this marriage of an abstract data type and multiple inheritance gives you something akin to a capability class without the complexity or overhead of multiple inheritance. In addition, because interfaces cannot have implementations nor data members, the need for virtual inheritance is eliminated.

Whether this is a bug or a feature is in the eyes of the beholder. In either case, if you understand multiple inheritance and Abstract Data Types in C++ you will be in a good position to move on to using some of the more advanced features of Java should you decide to learn that language as well.

The observer pattern and how it is implemented both in Java and C++ is covered in detail in Robert Martin's article "C++ and Java: A Critical Comparison," in the January 1997 issue of C++ Report.

### Summary

Today you learned how to overcome some of the limitations in single inheritance. You learned about the danger of percolating interfaces up the inheritance hierarchy, and the risks in casting down the inheritance hierarchy. You also learned how to use multiple inheritance, what problems multiple inheritance can create and how to solve them using virtual inheritance.

You also learned what Abstract Data Types are and how to create Abstract classes using pure virtual functions. You learned how to implement pure virtual functions and when and why you might do so. Finally, you saw how to implement the Observer Pattern using multiple inheritance and Abstract Data types.

### Q&A

  Q. What does percolating functionality upwards mean?
  A. This refers to the idea of moving shared functionality upwards into a common base class. If more than one class shares a function, it is desirable to find a common base class in which that function can be stored.
  Q. Is percolating upwards always a good thing?
  A. Yes, if you are percolating shared functionality upwards. No, if all you are moving is interface. That is, if all the derived classes can't use the method, it is a mistake to move it up into a common base class. If you do, you'll have to switch on the runtime type of the object before deciding if you can invoke the function.
  Q. Why is switching on the runtime type of an object bad?
  A. With large programs, the `switch` statements become big and hard to maintain. The point of virtual functions is to let the virtual table, rather than the programmer, determine the runtime type of the object.
  Q. Why is casting bad?
  A. Casting isn't bad if it is done in a way that is type-safe. If a function is called that knows that the object must be of a particular type, casting to that type is fine. Casting can be used to undermine the strong type checking in C++, and that is what you want to avoid. If you are switching on the runtime type of the object and then casting a pointer, that may be a warning sign that something is wrong with your design.
  Q. Why not make all functions virtual?
  A. Virtual functions are supported by a virtual function table, which incurs runtime overhead, both in the size of the program and in the performance of the program. If you have very small classes that you don't expect to subclass, you may not want to make any of the functions virtual.
  Q. When should the destructor be made virtual?
  A. Anytime you think the class will be subclassed, and a pointer to the base class will be used to access an object of the subclass. As a general rule of thumb, if you've made any functions in your class virtual, be sure to make the destructor virtual as well.
  Q. Why bother making an Abstract Data Type--why not just make it non-abstract and avoid creating any objects of that type?
  A. The purpose of many of the conventions in C++ is to enlist the compiler in finding bugs, so as to avoid runtime bugs in code that you give your customers. Making a class abstract, that is, giving it pure virtual functions, causes the compiler to flag any objects created of that abstract type as errors.

### Workshop

The Workshop provides quiz questions to help you solidify your understanding of the material covered, and exercises to provide you with experience in using what you've learned. Try to answer the quiz and exercise questions before checking the answers in Appendix D, and make sure you understand the answers before continuing to the next chapter.

#### Quiz

  1. What is a down cast?
  2. What is the `v-ptr`?
  3. If a round-rectangle has straight edges and rounded corners, and your `RoundRect` class inherits both from `Rectangle` and from `Circle`, and they in turn both inherit from `Shape`, how many `Shape`s are created when you create a `RoundRect`?
  4. If `Horse` and `Bird` inherit from `Animal` using public virtual inheritance, do their constructors initialize the `Animal` constructor? If `Pegasus` inherits from both `Horse` and `Bird`, how does it initialize `Animal`'s constructor?
  5. Declare a class `vehicle`, and make it an abstract data type.
  6. If a base class is an ADT, and it has three pure virtual functions, how many of these must be overridden in its derived classes?

#### Exercises

  1. Show the declaration for a class `JetPlane`, which inherits from `Rocket` and `Airplane`.
  2. Show the declaration for `747`, which inherits from the `JetPlane` class described in Exercise 1.
  3. Write a program that derives `Car` and `Bus` from the class `Vehicle`. Make `Vehicle` be an ADT with two pure virtual functions. Make `Car` and `Bus` not be ADTs.
  4. Modify the program in Exercise 3 so that `Car` is an ADT, and derive `SportsCar`, `Wagon`, and `Coupe` from `Car`. In the `Car` class, provide an implementation for one of the pure virtual functions in `Vehicle` and make it non-pure.