#

#

- Day 12
  - Inheritance
    - What Is Inheritance?
      - Inheritance and Derivation
        - Figure 12.1.
      - The Animal Kingdom
      - The Syntax of Derivation
    - Listing 12.1. Simple inheritance.
    - Private Versus Protected
    - Listing 12.2. Using a derived object.
    - Constructors and Destructors
    - Listing 12.3. Constructors and destructors called.
      - Passing Arguments to Base Constructors
    - Listing 12.4. Overloading constructors in derived classes.
    - Overriding Functions
    - Listing 12.5. Overriding a base class method
    - in a derived class.
    - Overloading Versus Overriding
      - Hiding the Base Class Method
    - Listing 12.6. Hiding methods.
    - Overriding Versus Hiding
      - Calling the Base Method
    - Listing 12.7. Calling base method from overridden method.
    - Virtual Methods
    - Listing 12.8. Using virtual methods.
    - Listing 12.9. Multiple virtual functions called in turn.
      - How Virtual Functions Work
        - Figure 12.2.
        - Figure 12.3.
        - Figure 12.4.
      - You Cant Get There from Here
      - Slicing
    - Listing 12.10. Data slicing when passing by value.
      - Virtual Destructors
      - Virtual Copy Constructors
    - Listing 12.11. Virtual copy constructor.
      - The Cost of Virtual Methods
    - Summary
    - Q&A
    - Workshop
      - Quiz
      - Exercises

## Day 12

## Inheritance

It is a fundamental aspect of human intelligence to seek out, recognize, and create relationships among concepts. We build hierarchies, matrices, networks, and other interrelationships to explain and understand the ways in which things interact. C++ attempts to capture this in inheritance hierarchies. Today you will learn

- What inheritance is.

- How to derive one class from another.

- What protected access is and how to use it.

- What virtual functions are.

### What Is Inheritance?

What is a dog? When you look at your pet, what do you see? A biologist sees a network of interacting organs, a physicist sees atoms and forces at work, and a taxonomist sees a representative of the species canine domesticus.

It is that last assessment that interests us at the moment. A dog is a kind of canine, a canine is a kind of mammal, and so forth. Taxonomists divide the world of living things into Kingdom, Phylum, Class, Order, Family, Genus, and Species.

This hierarchy establishes an is-a relationship. A dog is a kind of canine. We see this relationship everywhere: A Toyota is a kind of car, which is a kind of vehicle. A sundae is a kind of dessert, which is a kind of food.

What do we mean when we say something is a kind of something else? We mean that it is a specialization of that thing. That is, a car is a special kind of vehicle.

#### Inheritance and Derivation

The concept dog inherits, that is, it automatically gets, all the features of a mammal. Because it is a mammal, we know that it moves and that it breathes air--all mammals move and breathe air by definition. The concept of a dog adds the idea of barking, wagging its tail, and so forth to that definition. We can further divide dogs into hunting dogs and terriers, and we can divide terriers into Yorkshire Terriers, Dandie Dinmont Terriers, and so forth.

A Yorkshire Terrier is a kind of terrier, therefore it is a kind of dog, therefore a kind of mammal, therefore a kind of animal, and therefore a kind of living thing. This hierarchy is represented in Figure 12.1.
Figure 12.1.Hierarchy of `Animal`s.
C++ attempts to represent these relationships by enabling you to define classes that derive from one another. Derivation is a way of expressing the is-a relationship. You derive a new class, `Dog`, from the class `Mammal`. You don't have to state explicitly that dogs move, because they inherit that from `Mammal`.

  New Term: A class which adds new functionality to an existing class is said to derive from that original class. The original class is said to be the new class's base class.

If the `Dog` class derives from the `Mammal` class, then `Mammal` is a base class of `Dog`. Derived classes are supersets of their base classes. Just as dog adds certain features to the idea of mammal, the `Dog` class will add certain methods or data to the `Mammal` class.

Typically, a base class will have more than one derived class. Just as dogs, cats, and horses are all types of mammals, their classes would all derive from the `Mammal` class.

#### The Animal Kingdom

To facilitate the discussion of derivation and inheritance, this chapter will focus on the relationships among a number of classes representing animals. You can imagine that you have been asked to design a children's game--a simulation of a farm.

In time you will develop a whole set of farm animals, including horses, cows, dogs, cats, sheep, and so forth. You will create methods for these classes so that they can act in the ways the child might expect, but for now you'll stub-out each method with a simple `print` statement.

Stubbing-out a function means you'll write only enough to show that the function was called, leaving the details for later when you have more time. Please feel free to extend the minimal code provided in this chapter to enable the animals to act more realistically.

#### The Syntax of Derivation

When you declare a class, you can indicate what class it derives from by writing a colon after the class name, the type of derivation (public or otherwise), and the class from which it derives. The following is an example.

    class Dog : public Mammal

The type of derivation will be discussed later in this chapter. For now, always use `public`. The class from which you derive must have been declared earlier, or you will get a compiler error. Listing 12.1 illustrates how to declare a `Dog` class that is derived from a `Mammal` class.

Listing 12.1. Simple inheritance.

    1:     //Listing 12.1 Simple inheritance
    2:
    3:     #include <iostream.h>
    4:     enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
    5:
    6:     class Mammal
    7:     {
    8:     public:
    9:        // constructors
    10:       Mammal();
    11:       ~Mammal();
    12:
    13:       //accessors
    14:       int GetAge()const;
    15:       void SetAge(int);
    16:       int GetWeight() const;
    17:       void SetWeight();
    18:
    19:       //Other methods
    20:       void Speak();
    21:       void Sleep();
    22:
    23:
    24:    protected:
    25:       int itsAge;
    26:       int itsWeight;
    27:    };
    28:
    29:    class Dog : public Mammal
    30:    {
    31:    public:
    32:
    33:       // Constructors
    34:       Dog();
    35:       ~Dog();
    36:
    37:       // Accessors
    38:       BREED GetBreed() const;
    39:       void SetBreed(BREED);
    40:
    41:       // Other methods
    42:       // WagTail();
    43:       // BegForFood();
    44:
    45:    protected:
    46:       BREED itsBreed;
    47: };

`
` This program has no output because it is only a set of class declarations without their implementations. Nonetheless, there is much to see here.

Analysis: On lines 6-27, the `Mammal` class is declared. Note that in this example, `Mammal` does not derive from any other class. In the real world, mammals do derive--that is, mammals are kinds of animals. In a C++ program, you can represent only a fraction of the information you have about any given object. Reality is far too complex to capture all of it, so every C++ hierarchy is an arbitrary representation of the data available. The trick of good design is to represent the areas that you care about in a way that maps back to reality in a reasonably faithful manner.

The hierarchy has to begin somewhere; this program begins with `Mammal`. Because of this decision, some member variables that might properly belong in a higher base class are now represented here. For example, certainly all animals have an age and weight, so if `Mammal` is derived from `Animal`, we might expect to inherit those attributes. As it is, the attributes appear in the `Mammal` class.

To keep the program reasonably simple and manageable, only six methods have been put in the `Mammal` class--four accessor methods, `Speak()`, and `Sleep()`.

The `Dog` class inherits from `Mammal`, as indicated on line 29. Every `Dog` object will have three member variables: `itsAge`, `itsWeight`, and `itsBreed`. Note that the class declaration for `Dog` does not include the member variables `itsAge` and `itsWeight`. `Dog` objects inherit these variables from the `Mammal` class, along with all of `Mammal`'s methods except the copy operator and the constructors and destructor.

### Private Versus Protected

You may have noticed that a new access keyword, `protected`, has been introduced on lines 24 and 45 of Listing 12.1. Previously, class data had been declared `private`. However, `private` members are not available to derived classes. You could make `itsAge` and `itsWeight` public, but that is not desirable. You don't want other classes accessing these data members directly.

What you want is a designation that says, "Make these visible to this class and to classes that derive from this class." That designation is protected. Protected data members and functions are fully visible to derived classes, but are otherwise private.

There are, in total, three access specifiers: public, protected, and private. If a function has an object of your class, it can access all the public member data and functions. The member functions, in turn, can access all private data members and functions of their own class, and all protected data members and functions of any class from which they derive.

Thus, the function `Dog::WagTail()` can access the private data `itsBreed` and can access the protected data in the `Mammal` class.

Even if other classes are layered between `Mammal` and `Dog` (for example, `DomesticAnimals`), the `Dog` class will still be able to access the protected members of `Mammal`, assuming that these other classes all use public inheritance. Private inheritance is discussed on Day 15, "Advanced Inheritance."

Listing 12.2 demonstrates how to create objects of type `Dog` and access the data and functions of that type.

Listing 12.2. Using a derived object.

    1:     //Listing 12.2 Using a derived object
    2:
    3:     #include <iostream.h>
    4:     enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
    5:
    6:     class Mammal
    7:     {
    8:     public:
    9:        // constructors
    10:       Mammal():itsAge(2), itsWeight(5){}
    11:       ~Mammal(){}
    12:
    13:       //accessors
    14:       int GetAge()const { return itsAge; }
    15:       void SetAge(int age) { itsAge = age; }
    16:       int GetWeight() const { return itsWeight; }
    17:       void SetWeight(int weight) { itsWeight = weight; }
    18:
    19:       //Other methods
    20:       void Speak()const { cout << "Mammal sound!\n"; }
    21:       void Sleep()const { cout << "shhh. I'm sleeping.\n"; }
    22:
    23:
    24:    protected:
    25:       int itsAge;
    26:       int itsWeight;
    27:    };
    28:
    29:    class Dog : public Mammal
    30:    {
    31:    public:
    32:
    33:       // Constructors
    34:       Dog():itsBreed(YORKIE){}
    35:       ~Dog(){}
    36:
    37:       // Accessors
    38:       BREED GetBreed() const { return itsBreed; }
    39:       void SetBreed(BREED breed) { itsBreed = breed; }
    40:
    41:       // Other methods
    42:       void WagTail() { cout << "Tail wagging...\n"; }
    43:       void BegForFood() { cout << "Begging for food...\n"; }
    44:
    45:    private:
    46:       BREED itsBreed;
    47:    };
    48:
    49:    int main()
    50:    {
    51:       Dog fido;
    52:       fido.Speak();
    53:       fido.WagTail();
    54:       cout << "Fido is " << fido.GetAge() << " years old\n";
    55:     return 0;
    56: }

    Output: Mammal sound!
    Tail wagging...
    Fido is 2 years old

Analysis: On lines 6-27, the `Mammal` class is declared (all of its functions are inline to save space here). On lines 29-47, the `Dog` class is declared as a derived class of `Mammal`. Thus, by these declarations, all `Dog`s have an age, a weight, and a breed.

On line 51, a `Dog` is declared: `Fido`. `Fido` inherits all the attributes of a `Mammal`, as well as all the attributes of a `Dog`. Thus, `Fido` knows how to `WagTail()`, but also knows how to `Speak()` and `Sleep()`.

### Constructors and Destructors

`Dog` objects are `Mammal` objects. This is the essence of the is-a relationship. When `Fido` is created, his base constructor is called first, creating a `Mammal`. Then the `Dog` constructor is called, completing the construction of the `Dog` object. Because we gave `Fido` no parameters, the default constructor was called in each case. `Fido` doesn't exist until he is completely constructed, which means that both his `Mammal` part and his `Dog` part must be constructed. Thus, both constructors must be called.

When `Fido` is destroyed, first the `Dog` destructor will be called and then the destructor for the `Mammal` part of `Fido`. Each destructor is given an opportunity to clean up after its own part of `Fido`. Remember to clean up after your `Dog`! Listing 12.3 demonstrates this.

Listing 12.3. Constructors and destructors called.

    1:     //Listing 12.3 Constructors and destructors called.
    2:
    3:     #include <iostream.h>
    4:     enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
    5:
    6:     class Mammal
    7:     {
    8:     public:
    9:        // constructors
    10:       Mammal();
    11:       ~Mammal();
    12:
    13:       //accessors
    14:       int GetAge() const { return itsAge; }
    15:       void SetAge(int age) { itsAge = age; }
    16:       int GetWeight() const { return itsWeight; }
    17:       void SetWeight(int weight) { itsWeight = weight; }
    18:
    19:       //Other methods
    20:       void Speak() const { cout << "Mammal sound!\n"; }
    21:       void Sleep() const { cout << "shhh. I'm sleeping.\n"; }
    22:
    23:
    24:    protected:
    25:       int itsAge;
    26:       int itsWeight;
    27:    };
    28:
    29:    class Dog : public Mammal
    30:    {
    31:    public:
    32:
    33:       // Constructors
    34:       Dog();
    35:       ~Dog();
    36:
    37:       // Accessors
    38:       BREED GetBreed() const { return itsBreed; }
    39:       void SetBreed(BREED breed) { itsBreed = breed; }
    40:
    41:       // Other methods
    42:       void WagTail() { cout << "Tail wagging...\n"; }
    43:       void BegForFood() { cout << "Begging for food...\n"; }
    44:
    45:    private:
    46:       BREED itsBreed;
    47:    };
    48:
    49:    Mammal::Mammal():
    50:    itsAge(1),
    51:    itsWeight(5)
    52:    {
    53:       cout << "Mammal constructor...\n";
    54:    }
    55:
    56:    Mammal::~Mammal()
    57:    {
    58:       cout << "Mammal destructor...\n";
    59:    }
    60:
    61:    Dog::Dog():
    62:    itsBreed(YORKIE)
    63:    {
    64:       cout << "Dog constructor...\n";
    65:    }
    66:
    67:    Dog::~Dog()
    68:    {
    69:       cout << "Dog destructor...\n";
    70:    }
    71:    int main()
    72:    {
    73:       Dog fido;
    74:       fido.Speak();
    75:       fido.WagTail();
    76:       cout << "Fido is " << fido.GetAge() << " years old\n";
    77:     return 0;
    78: }

    Output: Mammal constructor...
    Dog constructor...
    Mammal sound!
    Tail wagging...
    Fido is 1 years old
    Dog destructor...
    Mammal destructor...

Analysis: Listing 12.3 is just like Listing 12.2, except that the constructors and destructors now print to the screen when called. `Mammal`'s constructor is called, then `Dog`'s. At that point the `Dog` fully exists, and its methods can be called. When `fido` goes out of scope, `Dog`'s destructor is called, followed by a call to `Mammal`'s destructor.

#### Passing Arguments to Base Constructors

It is possible that you'll want to overload the constructor of `Mammal` to take a specific age, and that you'll want to overload the `Dog` constructor to take a breed. How do you get the age and weight parameters passed up to the right constructor in `Mammal`? What if `Dog`s want to initialize weight but `Mammal`s don't?

Base class initialization can be performed during class initialization by writing the base class name, followed by the parameters expected by the base class. Listing 12.4 demonstrates this.

Listing 12.4. Overloading constructors in derived classes.

    1:     //Listing 12.4 Overloading constructors in derived classes
    2:
    3:     #include <iostream.h>
    4:     enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
    5:
    6:     class Mammal
    7:     {
    8:     public:
    9:        // constructors
    10:       Mammal();
    11:       Mammal(int age);
    12:       ~Mammal();
    13:
    14:       //accessors
    15:       int GetAge() const { return itsAge; }
    16:       void SetAge(int age) { itsAge = age; }
    17:       int GetWeight() const { return itsWeight; }
    18:       void SetWeight(int weight) { itsWeight = weight; }
    19:
    20:       //Other methods
    21:       void Speak() const { cout << "Mammal sound!\n"; }
    22:       void Sleep() const { cout << "shhh. I'm sleeping.\n"; }
    23:
    24:
    25:    protected:
    26:       int itsAge;
    27:       int itsWeight;
    28:    };
    29:
    30:    class Dog : public Mammal
    31:    {
    32:    public:
    33:
    34:       // Constructors
    35:       Dog();
    36:       Dog(int age);
    37:       Dog(int age, int weight);
    38:       Dog(int age, BREED breed);
    39:       Dog(int age, int weight, BREED breed);
    40:       ~Dog();
    41:
    42:       // Accessors
    43:       BREED GetBreed() const { return itsBreed; }
    44:       void SetBreed(BREED breed) { itsBreed = breed; }
    45:
    46:       // Other methods
    47:       void WagTail() { cout << "Tail wagging...\n"; }
    48:       void BegForFood() { cout << "Begging for food...\n"; }
    49:
    50:    private:
    51:       BREED itsBreed;
    52:    };
    53:
    54:    Mammal::Mammal():
    55:    itsAge(1),
    56:    itsWeight(5)
    57:    {
    58:       cout << "Mammal constructor...\n";
    59:    }
    60:
    61:    Mammal::Mammal(int age):
    62:    itsAge(age),
    63:    itsWeight(5)
    64:    {
    65:       cout << "Mammal(int) constructor...\n";
    66:    }
    67:
    68:    Mammal::~Mammal()
    69:    {
    70:       cout << "Mammal destructor...\n";
    71:    }
    72:
    73:    Dog::Dog():
    74:    Mammal(),
    75:    itsBreed(YORKIE)
    76:    {
    77:       cout << "Dog constructor...\n";
    78:    }
    79:
    80:    Dog::Dog(int age):
    81:    Mammal(age),
    82:    itsBreed(YORKIE)
    83:    {
    84:       cout << "Dog(int) constructor...\n";
    85:    }
    86:
    87:    Dog::Dog(int age, int weight):
    88:    Mammal(age),
    89:    itsBreed(YORKIE)
    90:    {
    91:       itsWeight = weight;
    92:       cout << "Dog(int, int) constructor...\n";
    93:    }
    94:
    95:    Dog::Dog(int age, int weight, BREED breed):
    96:    Mammal(age),
    97:    itsBreed(breed)
    98:    {
    99:       itsWeight = weight;
    100:      cout << "Dog(int, int, BREED) constructor...\n";
    101:   }
    102:
    103:   Dog::Dog(int age, BREED breed):
    104:   Mammal(age),
    105:   itsBreed(breed)
    106:   {
    107:      cout << "Dog(int, BREED) constructor...\n";
    108:   }
    109:
    110:   Dog::~Dog()
    111:   {
    112:      cout << "Dog destructor...\n";
    113:   }
    114:   int main()
    115:   {
    116:      Dog fido;
    117:      Dog rover(5);
    118:      Dog buster(6,8);
    119:      Dog yorkie (3,YORKIE);
    120:      Dog dobbie (4,20,DOBERMAN);
    121:      fido.Speak();
    122:      rover.WagTail();
    123:      cout << "Yorkie is " << yorkie.GetAge() << " years old\n";
    124:      cout << "Dobbie weighs ";
    125:      cout << dobbie.GetWeight() << " pounds\n";
    126:     return 0;
    127: }

> NOTE: The output has been numbered here so that each line can be referred to in the analysis.

    Output: 1:  Mammal constructor...
    2:  Dog constructor...
    3:  Mammal(int) constructor...
    4:  Dog(int) constructor...
    5:  Mammal(int) constructor...
    6:  Dog(int, int) constructor...
    7:  Mammal(int) constructor...
    8:  Dog(int, BREED) constructor....
    9:  Mammal(int) constructor...
    10: Dog(int, int, BREED) constructor...
    11: Mammal sound!
    12: Tail wagging...
    13: Yorkie is 3 years old.
    14: Dobbie weighs 20 pounds.
    15: Dog destructor. . .
    16: Mammal destructor...
    17: Dog destructor...
    18: Mammal destructor...
    19: Dog destructor...
    20: Mammal destructor...
    21: Dog destructor...
    22: Mammal destructor...
    23: Dog destructor...
    24: Mammal destructor...

Analysis: In Listing 12.4, `Mammal`'s constructor has been overloaded on line 11 to take an integer, the `Mammal`'s age. The implementation on lines 61-66 initializes `itsAge` with the value passed into the constructor and initializes `itsWeight` with the value `5`.

`Dog` has overloaded five constructors, on lines 35-39. The first is the default constructor. The second takes the age, which is the same parameter that the `Mammal` constructor takes. The third constructor takes both the age and the weight, the fourth takes the age and breed, and the fifth takes the age, weight, and breed.

Note that on line 74 `Dog`'s default constructor calls `Mammal`'s default constructor. Although it is not strictly necessary to do this, it serves as documentation that you intended to call the base constructor, which takes no parameters. The base constructor would be called in any case, but actually doing so makes your intentions explicit.

The implementation for the `Dog` constructor, which takes an integer, is on lines 80-85. In its initialization phase (lines 81-82), `Dog` initializes its base class, passing in the parameter, and then it initializes its breed.

Another `Dog` constructor is on lines 87-93. This one takes two parameters. Once again it initializes its base class by calling the appropriate constructor, but this time it also assigns `weight` to its base class's variable `itsWeight`. Note that you cannot assign to the base class variable in the initialization phase. Because `Mammal` does not have a constructor that takes this parameter, you must do this within the body of the `Dog`'s constructor.

Walk through the remaining constructors to make sure you are comfortable with how they work. Note what is initialized and what must wait for the body of the constructor.

The output has been numbered so that each line can be referred to in this analysis. The first two lines of output represent the instantiation of `Fido`, using the default constructor.

In the output, lines 3 and 4 represent the creation of `rover`. Lines 5 and 6 represent `buster`. Note that the `Mammal` constructor that was called is the constructor that takes one integer, but the `Dog` constructor is the constructor that takes two integers.

After all the objects are created, they are used and then go out of scope. As each object is destroyed, first the `Dog` destructor and then the `Mammal` destructor is called, five of each in total.

### Overriding Functions

A `Dog` object has access to all the member functions in class `Mammal`, as well as to any member functions, such as `WagTail()`, that the declaration of the `Dog` class might add. It can also override a base class function. Overriding a function means changing the implementation of a base class function in a derived class. When you make an object of the derived class, the correct function is called.

  New Term: When a derived class creates a function with the same return type and signature as a member function in the base class, but with a new implementation, it is said to be overriding that method.

When you override a function, it must agree in return type and in signature with the function in the base class. The signature is the function prototype other than the return type: that is, the name, the parameter list, and the keyword `const` if used.

  New Term: The signature of a function is its name, as well as the number and type of its parameters. The signature does not include the return type.

Listing 12.5 illustrates what happens if the `Dog` class overrides the `Speak()` method in `Mammal`. To save room, the accessor functions have been left out of these classes.

Listing 12.5. Overriding a base class methodin a derived class.

    1:     //Listing 12.5 Overriding a base class method in a derived class
    2:
    3:     #include <iostream.h>
    4:     enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
    5:
    6:     class Mammal
    7:     {
    8:     public:
    9:        // constructors
    10:       Mammal() { cout << "Mammal constructor...\n"; }
    11:       ~Mammal() { cout << "Mammal destructor...\n"; }
    12:
    13:       //Other methods
    14:       void Speak()const { cout << "Mammal sound!\n"; }
    15:       void Sleep()const { cout << "shhh. I'm sleeping.\n"; }
    16:
    17:
    18:    protected:
    19:       int itsAge;
    20:       int itsWeight;
    21:    };
    22:
    23:    class Dog : public Mammal
    24:    {
    25:    public:
    26:
    27:       // Constructors
    28:       Dog(){ cout << "Dog constructor...\n"; }
    29:       ~Dog(){ cout << "Dog destructor...\n"; }
    30:
    31:       // Other methods
    32:       void WagTail() { cout << "Tail wagging...\n"; }
    33:       void BegForFood() { cout << "Begging for food...\n"; }
    34:       void Speak()const { cout << "Woof!\n"; }
    35:
    36:    private:
    37:       BREED itsBreed;
    38:    };
    39:
    40:    int main()
    41:    {
    42:       Mammal bigAnimal;
    43:       Dog fido;
    44:       bigAnimal.Speak();
    45:       fido.Speak();
    46:     return 0;
    47: }

    Output: Mammal constructor...
    Mammal constructor...
    Dog constructor...
    Mammal sound!
    Woof!
    Dog destructor...
    Mammal destructor...
    Mammal destructor...

Analysis: On line 34, the `Dog` class overrides the `Speak()` method, causing `Dog` objects to say `Woof!` when the `Speak()` method is called. On line 42, a `Mammal` object, `bigAnimal`, is created, causing the first line of output when the `Mammal` constructor is called. On line 43, a `Dog` object, `fido`, is created, causing the next two lines of output, where the `Mammal` constructor and then the `Dog` constructor are called.

On line 44, the `Mammal` object calls its `Speak()` method, then on line 45, the `Dog` object calls its `Speak()` method. The output reflects that the correct methods were called. Finally, the two objects go out of scope and the destructors are called.

### Overloading Versus Overriding

These terms are similar, and they do similar things. When you overload a method, you create more than one method with the same name, but with a different signature. When you override a method, you create a method in a derived class with the same name as a method in the base class and the same signature.

#### Hiding the Base Class Method

In the previous listing, the `Dog` class's `Speak()` method hides the base class's method. This is just what is wanted, but it can have unexpected results. If `Mammal` has a method, `Move()`, which is overloaded, and `Dog` overrides that method, the `Dog` method will hide all of the `Mammal` methods with that name.

If `Mammal` overloads `Move()` as three methods--one that takes no parameters, one that takes an integer, and one that takes an integer and a direction--and `Dog` overrides just the `Move()` method that takes no parameters, it will not be easy to access the other two methods using a `Dog` object. Listing 12.6 illustrates this problem.

Listing 12.6. Hiding methods.

    1:     //Listing 12.6 Hiding methods
    2:
    3:     #include <iostream.h>
    4:
    5:     class Mammal
    6:     {
    7:     public:
    8:        void Move() const { cout << "Mammal move one step\n"; }
    9:        void Move(int distance) const
    10:       {
    11:          cout << "Mammal move ";
    12:          cout << distance <<" _steps.\n";
    13:       }
    14:    protected:
    15:       int itsAge;
    16:       int itsWeight;
    17:    };
    18:
    19:    class Dog : public Mammal
    20:    {
    21:    public:
    22: // You may receive a warning that you are hiding a function!
    23:       void Move() const { cout << "Dog move 5 steps.\n"; }
    24:    };
    25:
    26:    int main()
    27:    {
    28:       Mammal bigAnimal;
    29:       Dog fido;
    30:       bigAnimal.Move();
    31:       bigAnimal.Move(2);
    32:       fido.Move();
    33:       // fido.Move(10);
    34:     return 0;
    35: }

    Output: Mammal move one step
    Mammal move 2 steps.
    Dog move 5 steps.

Analysis: All of the extra methods and data have been removed from these classes. On lines 8 and 9, the `Mammal` class declares the overloaded `Move()` methods. On line 18, `Dog` overrides the version of `Move()` with no parameters. These are invoked on lines 30-32, and the output reflects this as executed.

Line 33, however, is commented out, as it causes a compile-time error. While the `Dog` class could have called the `Move(int)` method if it had not overridden the version of`Move()` without parameters, now that it has done so it must override both if it wishes to use both. This is reminiscent of the rule that if you supply any constructor, the compiler will no longer supply a default constructor.

It is a common mistake to hide a base class method when you intend to override it, by forgetting to include the keyword `const`. `const` is part of the signature, and leaving it off changes the signature and thus hides the method rather than overriding it.

### Overriding Versus Hiding

In the next section, virtual methods are described. Overriding a virtual method supports polymorphism--hiding it undermines polymorphism. You'll see more on this very soon.

#### Calling the Base Method

If you have overridden the base method, it is still possible to call it by fully qualifying the name of the method. You do this by writing the base name, followed by two colons and then the method name. For example: `Mammal::Move()`.

It would have been possible to rewrite line 28 in Listing 12.6 so that it would compile, by writing

    28:     fido.Mammal::Move(10);

This calls the `Mammal` method explicitly. Listing 12.7 fully illustrates this idea.

Listing 12.7. Calling base method from overridden method.

    1:     //Listing 12.7 Calling base method from overridden method.
    2:
    3:     #include <iostream.h>
    4:
    5:     class Mammal
    6:     {
    7:     public:
    8:        void Move() const { cout << "Mammal move one step\n"; }
    9:        void Move(int distance) const
    10:       {
    11:            cout << "Mammal move " << distance;
    12:            cout << " steps.\n";
    13:       }
    14:
    15:    protected:
    16:       int itsAge;
    17:       int itsWeight;
    18:    };
    19:
    20:    class Dog : public Mammal
    21:    {
    22:    public:
    23:       void Move()const;
    24:
    25:    };
    26:
    27:    void Dog::Move() const
    28:    {
    29:       cout << "In dog move...\n";
    30:       Mammal::Move(3);
    31:    }
    32:
    33:    int main()
    34:    {
    35:       Mammal bigAnimal;
    36:       Dog fido;
    37:       bigAnimal.Move(2);
    38:       fido.Mammal::Move(6);
    39:     return 0;
    40: }

    Output: Mammal move 2 steps.
    Mammal move 6 steps.

Analysis: On line 35, a `Mammal`, `bigAnimal`, is created, and on line 36, a `Dog`, `fido`, is created. The method call on line 37 invokes the `Move()` method of `Mammal`, which takes an `int`.

The programmer wanted to invoke `Move(int)` on the `Dog` object, but had a problem. `Dog` overrides the `Move()` method, but does not overload it and does not provide a version that takes an `int`. This is solved by the explicit call to the base class `Move(int)` method on line 33.

> DO extend the functionality of tested classes by deriving. DO change the behavior of certain functions in the derived class by overriding the base class methods. DON'T hide a base class function by changing the function signature.

### Virtual Methods

This chapter has emphasized the fact that a `Dog` object is a `Mammal` object. So far that has meant only that the `Dog` object has inherited the attributes (data) and capabilities (methods) of its base class. In C++ the is-a relationship runs deeper than that, however.

C++ extends its polymorphism to allow pointers to base classes to be assigned to derived class objects. Thus, you can write

    Mammal* pMammal = new Dog;

This creates a new `Dog` object on the heap and returns a pointer to that object, which it assigns to a pointer to `Mammal`. This is fine, because a dog is a mammal.

> NOTE: This is the essence of polymorphism. For example, you could create many different types of windows, including dialog boxes, scrollable windows, and list boxes, and give them each a virtual `draw()` method. By creating a pointer to a window and assigning dialog boxes and other derived types to that pointer, you can call `draw()` without regard to the actual run-time type of the object pointed to. The correct `draw()` function will be called.

You can then use this pointer to invoke any method on `Mammal`. What you would like is for those methods that are overridden in `Dog()` to call the correct function. Virtual functions let you do that. Listing 12.8 illustrates how this works, and what happens with non-virtual methods.

Listing 12.8. Using virtual methods.

    1:     //Listing 12.8 Using virtual methods
    2:
    3:     #include <iostream.h>
    4:
    5:     class Mammal
    6:     {
    7:     public:
    8:        Mammal():itsAge(1) { cout << "Mammal constructor...\n"; }
    9:        ~Mammal() { cout << "Mammal destructor...\n"; }
    10:       void Move() const { cout << "Mammal move one step\n"; }
    11:       virtual void Speak() const { cout << "Mammal speak!\n"; }
    12:    protected:
    13:       int itsAge;
    14:
    15:    };
    16:
    17:    class Dog : public Mammal
    18:    {
    19:    public:
    20:       Dog() { cout << "Dog Constructor...\n"; }
    21:       ~Dog() { cout << "Dog destructor...\n"; }
    22:       void WagTail() { cout << "Wagging Tail...\n"; }
    23:       void Speak()const { cout << "Woof!\n"; }
    24:       void Move()const { cout << "Dog moves 5 steps...\n"; }
    25:    };
    26:
    27:    int main()
    28:    {
    29:
    30:       Mammal *pDog = new Dog;
    31:       pDog->Move();
    32:       pDog->Speak();
    33:
    34:     return 0;
    35: }

    Output: Mammal constructor...
    Dog Constructor...
    Mammal move one step
    Woof!

Analysis: On line 11, `Mammal` is provided a virtual method--`speak()`. The designer of this class thereby signals that she expects this class eventually to be another class's base type. The derived class will probably want to override this function.

On line 30, a pointer to `Mammal` is created (`pDog`), but it is assigned the address of a new `Dog` object. Because a dog is a mammal, this is a legal assignment. The pointer is then used to call the `Move()` function. Because the compiler knows `pDog` only to be a `Mammal`, it looks to the `Mammal` object to find the `Move()` method.

On line 32, the pointer then calls the `Speak()` method. Because `Speak()` is virtual, the `Speak()` method overridden in `Dog` is invoked.

This is almost magical. As far as the calling function knew, it had a `Mammal` pointer, but here a method on `Dog` was called. In fact, if you had an array of pointers to `Mammal`, each of which pointed to a subclass of `Mammal`, you could call each in turn and the correct function would be called. Listing 12.9 illustrates this idea.

Listing 12.9. Multiple virtual functions called in turn.

    1:      //Listing 12.9 Multiple virtual functions called in turn
    2:
    3:      #include <iostream.h>
    4:
    5:     class Mammal
    6:     {
    7:     public:
    8:        Mammal():itsAge(1) {  }
    9:        ~Mammal() { }
    10:       virtual void Speak() const { cout << "Mammal speak!\n"; }
    11:    protected:
    12:       int itsAge;
    13:    };
    14:
    15:    class Dog : public Mammal
    16:    {
    17:    public:
    18:       void Speak()const { cout << "Woof!\n"; }
    19:    };
    20:
    21:
    22:    class Cat : public Mammal
    23:    {
    24:    public:
    25:       void Speak()const { cout << "Meow!\n"; }
    26:    };
    27:
    28:
    29:    class Horse : public Mammal
    30:    {
    31:    public:
    32:       void Speak()const { cout << "Winnie!\n"; }
    33:    };
    34:
    35:    class Pig : public Mammal
    36:    {
    37:    public:
    38:       void Speak()const { cout << "Oink!\n"; }
    39:    };
    40:
    41:    int main()
    42:    {
    43:       Mammal* theArray[5];
    44:       Mammal* ptr;
    45:       int choice, i;
    46:       for ( i = 0; i<5; i++)
    47:       {
    48:          cout << "(1)dog (2)cat (3)horse (4)pig: ";
    49:          cin >> choice;
    50:          switch (choice)
    51:          {
    52:             case 1: ptr = new Dog;
    53:             break;
    54:             case 2: ptr = new Cat;
    55:             break;
    56:             case 3: ptr = new Horse;
    57:             break;
    58:             case 4: ptr = new Pig;
    59:             break;
    60:             default: ptr = new Mammal;
    61:             break;
    62:          }
    63:          theArray[i] = ptr;
    64:       }
    65:       for (i=0;i<5;i++)
    66:          theArray[i]->Speak();
    67:     return 0;
    68: }

    Output: (1)dog (2)cat (3)horse (4)pig: 1
    (1)dog (2)cat (3)horse (4)pig: 2
    (1)dog (2)cat (3)horse (4)pig: 3
    (1)dog (2)cat (3)horse (4)pig: 4
    (1)dog (2)cat (3)horse (4)pig: 5
    Woof!
    Meow!
    Winnie!
    Oink!
    Mammal speak!

Analysis: This stripped-down program, which provides only the barest functionality to each class, illustrates virtual functions in their purest form. Four classes are declared; `Dog`,`Cat`,`Horse`, and `Pig` are all derived from `Mammal`.

On line 10, `Mammal`'s `Speak()` function is declared to be virtual. On lines 18, 25, 32, and 38, the four derived classes override the implementation of `Speak()`.

The user is prompted to pick which objects to create, and the pointers are added to the array on lines 46-64.

> NOTE: At compile time, it is impossible to know which objects will be created, and thus which `Speak()` methods will be invoked. The pointer `ptr` is bound to its object at runtime. This is called dynamic binding, or run-time binding, as opposed to static binding, or compile-time binding.

#### How Virtual Functions Work

When a derived object, such as a `Dog` object, is created, first the constructor for the base class is called and then the constructor for the derived class is called. Figure 12.2 shows what the `Dog` object looks like after it is created. Note that the `Mammal` part of the object is contiguous in memory with the `Dog` part.
Figure 12.2. The `Dog` object after it is created.
When a virtual function is created in an object, the object must keep track of that function. Many compilers build a virtual function table, called a v-table. One of these is kept for each type, and each object of that type keeps a virtual table pointer (called a `vptr` or v-pointer), which points to that table.

While implementations vary, all compilers must accomplish the same thing, so you won't be too wrong with this description.
Figure 12.3. The v-table of a `Mammal`.
Each object's `vptr` points to the v-table which, in turn, has a pointer to each of the virtual functions. (Note, pointers to functions will be discussed in depth on Day 14, "Special Classes and Functions.") When the `Mammal` part of the `Dog` is created, the `vptr` is initialized to point to the correct part of the v-table, as shown in Figure 12.3.
Figure 12.4. The v-table of a `Dog`.
When the `Dog` constructor is called, and the `Dog` part of this object is added, the `vptr` is adjusted to point to the virtual function overrides (if any) in the `Dog` object (see Figure 12.4) .

When a pointer to a `Mammal` is used, the `vptr` continues to point to the correct function, depending on the "real" type of the object. Thus, when `Speak()` is invoked, the correct function is invoked.

#### You Cant Get There from Here

If the `Dog` object had a method, `WagTail()`, which is not in the `Mammal`, you could not use the pointer to `Mammal` to access that method (unless you cast it to be a pointer to `Dog`). Because `WagTail()` is not a virtual function, and because it is not in a `Mammal` object, you can't get there without either a `Dog` object or a `Dog` pointer.

Although you can transform the `Mammal` pointer into a `Dog` pointer, there are usually far better and safer ways to call the `WagTail()` method. C++ frowns on explicit casts because they are error-prone. This subject will be addressed in depth when multiple inheritance is covered tomorrow, and again when templates are covered on Day 20, "Exceptions and Error Handling."

#### Slicing

Note that the virtual function magic operates only on pointers and references. Passing an object by value will not enable the virtual functions to be invoked. Listing 12.10 illustrates this problem.

Listing 12.10. Data slicing when passing by value.

    1:      //Listing 12.10 Data slicing with passing by value
    2:
    3:      #include <iostream.h>
    4:
    5:     enum BOOL { FALSE, TRUE };
    6:     class Mammal
    7:     {
    8:     public:
    9:        Mammal():itsAge(1) {  }
    10:       ~Mammal() { }
    11:       virtual void Speak() const { cout << "Mammal speak!\n"; }
    12:    protected:
    13:       int itsAge;
    14:    };
    15:
    16:    class Dog : public Mammal
    17:    {
    18:    public:
    19:       void Speak()const { cout << "Woof!\n"; }
    20:    };
    21:
    22:    class Cat : public Mammal
    23:    {
    24:    public:
    25:       void Speak()const { cout << "Meow!\n"; }
    26:    };
    27:
    28     void ValueFunction (Mammal);
    29:    void PtrFunction   (Mammal*);
    30:    void RefFunction (Mammal&);
    31:    int main()
    32:    {
    33:       Mammal* ptr=0;
    34:       int choice;
    35:       while (1)
    36:       {
    37:          BOOL fQuit = FALSE;
    38:          cout << "(1)dog (2)cat (0)Quit: ";
    39:          cin >> choice;
    40:          switch (choice)
    41:          {
    42:             case 0: fQuit = TRUE;
    43:             break;
    44:             case 1: ptr = new Dog;
    45:             break;
    46:             case 2: ptr = new Cat;
    47:             break;
    48:             default: ptr = new Mammal;
    49:             break;
    50:          }
    51:           if (fQuit)
    52:             break;
    53:           PtrFunction(ptr);
    54:           RefFunction(*ptr);
    55:           ValueFunction(*ptr);
    56:       }
    57:        return 0;
    58:    }
    59:
    60:    void ValueFunction (Mammal MammalValue)
    61:    {
    62:       MammalValue.Speak();
    63:    }
    64:
    65:    void PtrFunction (Mammal * pMammal)
    66:    {
    67:       pMammal->Speak();
    68:    }
    69:
    70:    void RefFunction (Mammal & rMammal)
    71:    {
    72:       rMammal.Speak();
    73: }

    Output: (1)dog (2)cat (0)Quit: 1
    Woof
    Woof
    Mammal Speak!
    (1)dog (2)cat (0)Quit: 2
    Meow!
    Meow!
    Mammal Speak!
    (1)dog (2)cat (0)Quit: 0

Analysis: On lines 6-26, stripped-down versions of the `Mammal`, `Dog`, and `Cat` classes are declared. Three functions are declared--`PtrFunction()`, `RefFunction()`, and `ValueFunction()`. They take a pointer to a `Mammal`, a `Mammal` reference, and a `Mammal` object, respectively. All three functions then do the same thing--they call the `Speak()` method.

The user is prompted to choose a `Dog` or `Cat`, and based on the choice he makes, a pointer to the correct type is created on lines 44-49.

In the first line of the output, the user chooses `Dog`. The `Dog` object is created on the free store on line 44. The `Dog` is then passed as a pointer, as a reference, and by value to the three functions.

The pointer and references all invoke the virtual functions, and the `Dog->Speak()` member function is invoked. This is shown on the first two lines of output after the user's choice.

The dereferenced pointer, however, is passed by value. The function expects a `Mammal` object, and so the compiler slices down the `Dog` object to just the `Mammal` part. At that point, the `Mammal` `Speak()` method is called, as reflected in the third line of output after the user's choice.

This experiment is then repeated for the `Cat` object, with similar results.

#### Virtual Destructors

It is legal and common to pass a pointer to a derived object when a pointer to a base object is expected. What happens when that pointer to a derived subject is deleted? If the destructor is virtual, as it should be, the right thing happens--the derived class's destructor is called. Because the derived class's destructor will automatically invoke the base class's destructor, the entire object will be properly destroyed.

The rule of thumb is this: If any of the functions in your class are virtual, the destructor should be as well.

#### Virtual Copy Constructors

As previously stated, no constructor can be virtual. Nonetheless, there are times when your program desperately needs to be able to pass in a pointer to a base object and have a copy of the correct derived object that is created. A common solution to this problem is to create a `Clone()` method in the base class and to make that be virtual. The `Clone()` method creates a new object copy of the current class, and returns that object.

Because each derived class overrides the `Clone()` method, a copy of the derived class is created. Listing 12.11 illustrates how this is used.

Listing 12.11. Virtual copy constructor.

    1:     //Listing 12.11 Virtual copy constructor
    2:
    3:     #include <iostream.h>
    4:
    5:     class Mammal
    6:     {
    7:     public:
    8:        Mammal():itsAge(1) { cout << "Mammal constructor...\n"; }
    9:        ~Mammal() { cout << "Mammal destructor...\n"; }
    10:       Mammal (const Mammal & rhs);
    11:       virtual void Speak() const { cout << "Mammal speak!\n"; }
    12:       virtual Mammal* Clone() { return new Mammal(*this); }
    13:       int GetAge()const { return itsAge; }
    14:    protected:
    15:       int itsAge;
    16:    };
    17:
    18:    Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge())
    19:    {
    20:       cout << "Mammal Copy Constructor...\n";
    21:    }
    22:
    23:    class Dog : public Mammal
    24:    {
    25:    public:
    26:       Dog() { cout << "Dog constructor...\n"; }
    27:       ~Dog() { cout << "Dog destructor...\n"; }
    28:       Dog (const Dog & rhs);
    29:       void Speak()const { cout << "Woof!\n"; }
    30:       virtual Mammal* Clone() { return new Dog(*this); }
    31:    };
    32:
    33:    Dog::Dog(const Dog & rhs):
    34:    Mammal(rhs)
    35:    {
    36:       cout << "Dog copy constructor...\n";
    37:    }
    38:
    39:    class Cat : public Mammal
    40:    {
    41:    public:
    42:       Cat() { cout << "Cat constructor...\n"; }
    43:       ~Cat() { cout << "Cat destructor...\n"; }
    44:       Cat (const Cat &);
    45:       void Speak()const { cout << "Meow!\n"; }
    46:       virtual Mammal* Clone() { return new Cat(*this); }
    47:    };
    48:
    49:    Cat::Cat(const Cat & rhs):
    50:    Mammal(rhs)
    51:    {
    52:       cout << "Cat copy constructor...\n";
    53:    }
    54:
    55:    enum ANIMALS { MAMMAL, DOG, CAT};
    56:    const int NumAnimalTypes = 3;
    57:    int main()
    58:    {
    59:       Mammal *theArray[NumAnimalTypes];
    60:       Mammal* ptr;
    61:       int choice, i;
    62:       for ( i = 0; i<NumAnimalTypes; i++)
    63:       {
    64:          cout << "(1)dog (2)cat (3)Mammal: ";
    65:          cin >> choice;
    66:          switch (choice)
    67:          {
    68:             case DOG: ptr = new Dog;
    69:             break;
    70:             case CAT: ptr = new Cat;
    71:             break;
    72:             default: ptr = new Mammal;
    73:             break;
    74:          }
    75:          theArray[i] = ptr;
    76:       }
    77:       Mammal *OtherArray[NumAnimalTypes];
    78:       for (i=0;i<NumAnimalTypes;i++)
    79:       {
    80:          theArray[i]->Speak();
    81:          OtherArray[i] = theArray[i]->Clone();
    82:       }
    83:       for (i=0;i<NumAnimalTypes;i++)
    84:          OtherArray[i]->Speak();
    25:     return 0;
    86: }

    1:  (1)dog (2)cat (3)Mammal: 1
    2:  Mammal constructor...
    3:  Dog constructor...
    4:  (1)dog (2)cat (3)Mammal: 2
    5:  Mammal constructor...
    6:  Cat constructor...
    7:  (1)dog (2)cat (3)Mammal: 3
    8:  Mammal constructor...
    9:  Woof!
    10: Mammal Copy Constructor...
    11: Dog copy constructor...
    12: Meow!
    13: Mammal Copy Constructor...
    14: Cat copy constructor...
    15: Mammal speak!
    16: Mammal Copy Constructor...
    17: Woof!
    18: Meow!
    19: Mammal speak!

Analysis: Listing 12.11 is very similar to the previous two listings, except that a new virtual method has been added to the `Mammal` class: `Clone()`. This method returns a pointer to a new `Mammal` object by calling the copy constructor, passing in itself (`*this`) as a `const` reference.

`Dog` and `Cat` both override the `Clone()` method, initializing their data and passing in copies of themselves to their own copy constructors. Because `Clone()` is virtual, this will effectively create a virtual copy constructor, as shown on line 81.

The user is prompted to choose dogs, cats, or mammals, and these are created on lines 62-74. A pointer to each choice is stored in an array on line 75.

As the program iterates over the array, each object has its `Speak()` and its `Clone()` methods called, in turn, on lines 80 and 81. The result of the `Clone()` call is a pointer to a copy of the object, which is then stored in a second array on line 81.

On line 1 of the output, the user is prompted and responds with `1`, choosing to create a dog. The `Mammal` and `Dog` constructors are invoked. This is repeated for `Cat` and for `Mammal` on lines 4-8 of the constructor.

Line 9 of the constructor represents the call to `Speak()` on the first object, the `Dog`. The virtual `Speak()` method is called, and the correct version of `Speak()` is invoked. The `Clone()` function is then called, and as this is also virtual, `Dog`'s `Clone()` method is invoked, causing the `Mammal` constructor and the `Dog` copy constructor to be called.

The same is repeated for `Cat` on lines 12-14, and then for `Mammal` on lines 15 and 16. Finally, the new array is iterated, and each of the new objects has `Speak()` invoked.

#### The Cost of Virtual Methods

Because objects with virtual methods must maintain a v-table, there is some overhead in having virtual methods. If you have a very small class from which you do not expect to derive other classes, there may be no reason to have any virtual methods at all.

Once you declare any methods virtual, you've paid most of the price of the v-table (although each entry does add a small memory overhead). At that point, you'll want the destructor to be virtual, and the assumption will be that all other methods probably will be virtual as well. Take a long hard look at any non-virtual methods, and be certain you understand why they are not virtual.

> DO use virtual methods when you expect to derive from a class. DO use a virtual destructor if any methods are virtual. DON'T mark the constructor as virtual.

### Summary

Today you learned how derived classes inherit from base classes. This chapter discussed public inheritance and virtual functions. Classes inherit all the public and protected data and functions from their base classes.

Protected access is public to derived classes and private to all other objects. Even derived classes cannot access private data or functions in their base classes.

Constructors can be initialized before the body of the constructor. It is at this time that base constructors are invoked and parameters can be passed to the base class.

Functions in the base class can be overridden in the derived class. If the base class functions are virtual, and if the object is accessed by pointer or reference, the derived class's functions will be invoked, based on the run-time type of the object pointed to.

Methods in the base class can be invoked by explicitly naming the function with the prefix of the base class name and two colons. For example, if `Dog` inherits from `Mammal`, `Mammal`'s `walk()` method can be called with `Mammal::walk()`.

In classes with virtual methods, the destructor should almost always be made virtual. A virtual destructor ensures that the derived part of the object will be freed when `delete` is called on the pointer. Constructors cannot be virtual. Virtual copy constructors can be effectively created by making a virtual member function that calls the copy constructor.

### Q&A

  Q. Are inherited members and functions passed along to subsequent generations? If Dog derives from Mammal, and Mammal derives from Animal, does Dog inherit Animal's functions and data?
  A. Yes. As derivation continues, derived classes inherit the sum of all the functions and data in all their base classes.
  Q. If, in the example above, Mammal overrides a function in Animal, which does Dog get, the original or the overridden function?
  A. If `Dog` inherits from `Mammal`, it gets the function in the state `Mammal` has it: the overridden function.
  Q. Can a derived class make a public base function private?
  A. Yes, and it remains private for all subsequent derivation.
  Q. Why not make all class functions virtual?
  A. There is overhead with the first virtual function in the creation of a v-table. After that, the overhead is trivial. Many C++ programmers feel that if one function is virtual, all others should be. Other programmers disagree, feeling that there should always be a reason for what you do.
  Q. If a function (SomeFunc()) is virtual in a base class and is also overloaded, so as to take either an integer or two integers, and the derived class overrides the form taking one integer, what is called when a pointer to a derived object calls the two-integer form?
  A. The overriding of the one-`int` form hides the entire base class function, and thus you will get a compile error complaining that that function requires only one `int`.

### Workshop

The Workshop provides quiz questions to help you solidify your understanding of the material that was 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 v-table?
  2. What is a virtual destructor?
  3. How do you show the declaration of a virtual constructor?
  4. How can you create a virtual copy constructor?
  5. How do you invoke a base member function from a derived class in which you've overridden that function?
  6. How do you invoke a base member function from a derived class in which you have not overridden that function?
  7. If a base class declares a function to be virtual, and a derived class does not use the term virtual when overriding that class, is it still virtual when inherited by a third-generation class?
  8. What is the `protected` keyword used for?

#### Exercises

  1. Show the declaration of a virtual function that takes an integer parameter and returns `void`.
  2. Show the declaration of a class `Square`, which derives from `Rectangle`, which in turn derives from `Shape`.
  3. If, in Exercise 2, `Shape` takes no parameters, `Rectangle` takes two (`length` and `width`), but `Square` takes only one (`length`), show the constructor initialization for `Square`.
  4. Write a virtual copy constructor for the class `Square` (in Exercise 3).
  5. BUG BUSTERS: What is wrong with this code snippet?

    void SomeFunction (Shape);
    Shape * pRect = new Rectangle;
    SomeFunction(*pRect);

  6. BUG BUSTERS: What is wrong with this code snippet?

    class Shape()
    {
    public:
         Shape();
         virtual ~Shape();
         virtual Shape(const Shape&);
    };