12.x — Chapter 12 comprehensive quiz

And so our journey through C++’s inheritance and virtual functions comes to an end. Fret not, dear reader, for there are plenty of other areas of C++ to explore as we move forward.

Chapter summary

C++ allows you to set base class pointers and references to a derived object. This is useful when we want to write a function or array that can work with any type of object derived from a base class.

Without virtual functions, base class pointers and references to a derived class will only have access to base class member variables and versions of functions.

A virtual function is a special type of function that resolves to the most-derived version of the function (called an override) that exists between the base and derived class. To be considered an override, the derived class function must have the same signature and return type as the virtual base class function. The one exception is for covariant return types, which allow an override to return a pointer or reference to a derived class if the base class function returns a pointer or reference to the base class.

A function that is intended to be an override should use the override specifier to ensure that it is actually an override.

The final specifier can be used to prevent overrides of a function or class.

If you intend to use virtual functions, you should make your destructor virtual, so the proper destructor is called if a pointer to the base class is deleted.

You can ignore virtual resolution by using the scope resolution operator to directly specifying which classes version of the function you want: e.g. base.Base::getName()

Early binding occurs when the compiler encounters a direct function call. The compiler or linker can resolve these function calls directly. Late binding occurs when a function pointer is called. In these cases, which function will be called can not be resolved until runtime. Virtual functions use late binding and a virtual table to determine which version of the function to call.

Using virtual functions has a cost: virtual functions take longer to call, and the necessity of the virtual table increases the size of every object containing a virtual function by one pointer.

A virtual function can be made pure virtual/abstract by assigning it to 0. A class containing a pure virtual function is called an abstract class, and can not be instantiated. A class that inherits pure virtual functions must concretely define them or it will also be considered abstract. Pure virtual functions can have a body, but they are still considered abstract.

An interface class is one with no member variables and all pure virtual functions. These are often named starting with a capital I.

A virtual base class is a base class that is only included once, no matter how many times it is inherited by an object.

When a derived class is assigned to a base class object, the base class only receives a copy of the base portion of the derived class. This is called object slicing.

Dynamic casting can be used to convert a pointer to a base class object into a pointer to a derived class object. This is called downcasting. A failed conversion will return a null pointer.

The easiest way to overload operator<< for inherited classes is to write an overloaded operator<< for the most-base class, and then call a virtual member function to do the printing.

Quiz time

1) Each of the following programs has some kind of defect. Inspect each program (visually, not by compiling) and determine what is wrong with the program. The output of each program is supposed to be “Derived”.


Show Solution


Show Solution


Show Solution


Show Solution


Show Solution


Show Solution

2a) Create an abstract class named Shape. This class should have three functions: a pure virtual print function that takes and returns a std::ostream, an overloaded operator<< and an empty virtual destructor.

Show Solution

2b) Derive two classes from Shape: a Triangle, and a Circle. The Triangle should have 3 Points as members. The Circle should have one center Point, and an integer radius. Overload the print() function so the following program runs:

This should print:

Circle(Point(1, 2, 3), radius 7)
Triangle(Point(1, 2, 3), Point(4, 5, 6), Point(7, 8, 9))

Here’s a Point class you can use:

Show Solution

2c) Given the above classes (Point, Shape, Circle, and Triangle), finish the following program:

Hint: You’ll need to add a getRadius() function to Circle, and downcast a Shape* into a Circle* to access it.

Show Solution

13.1 -- Function templates
12.10 -- Printing inherited classes using operator<<

23 comments to 12.x — Chapter 12 comprehensive quiz

  • Sean Kelly

    Good afternoon Alex,

    just wondering if pop_back() is the same as delete in terms of pointers
    just being removed from the vector and still taking memory or being deleted
    all together. I’m assuming it’s the former.


    • Alex

      pop_back does not do a delete. If you have a vector of pointers and you do a pop_back, you will need to delete the pointer subsequently.

  • Jasur

    when we print vector  

    it prints address.

    in prints as necessary.
    Can you explain it why, please?

    • Alex

      Vector v is a vector of pointers to Shapes. So v[i] is a single pointer to a Shape. So if you print v[i], you’re printing the address of the Shape, not the actual Shape. To print the actual shape, we need to dereference the pointer, which is *v[i].

  • C++ Learner

    why are we calling the function always with base class what is the advantage of that?

    • Alex

      In a program like this, there is none. However, it’s to teach you the principles that you can then apply to other programs that are useful. For example, you could have an array of pointers to Base objects -- however, these could actually point to Derived objects or anything else derived from Base. This allows us to create arrays that store classes of different types, as long as they’re all derived from a common parent.

  • Chris

    Hey Alex,
    I tried to move each class in a different header and cpp file. But if i include everything each class needs in its own header i will have for instance multiple inclusions of the class "Shape.h" in the final program. Should i just include nothing in each header so that the classes only work if i include them in the correct order in the main.cpp file or i should i make them work independently and let the header guards do the work ?

    • Alex

      Each header and code file should be as independent as possible, and take care of all of its own dependencies. It’s okay to have multiple files including Shape.h. If you ever get into a situation where the order of the #includes matters, you’ve probably done something wrong.

  • Gapo

    I’ve done it like this

  • Hugh Mungus

    Hey Alex,
    Thanks for putting the effort in maintaining this site.

    I might have cheated a little bit in the last question.

  • loveu

    Qn 1a) base class is missing a const in the getName() function

  • Elruin

    There is no return in main() in last quiz.

  • ali

    hello, Alex, I tried something in the getLargestRadius()

    the out put for this in main

    not circle this is triangle it didn’t has a radius
    The largest radius is: 7
    why not it be:
    the largest radius is : not circle this is triangle it didn’t has a radiusn

    • Alex

      This happens because the std::cout in main() and in getLargestRadius() are independent.

      When the compiler encounters this:

      It first evaluates getLargestRadius(). This prints “not circle this is triangle…” and returns the value 7. At that point, the rest of the expression evaluates as if you had typed:

      So it’s clear that the “not a circle” text executes before the “The largest radius” text.

  • Philip

    In the last paragraph before the quiz you have operator<lt instead of operator<<.

  • Tuan

    The quiz 1f is hide under solution of quiz 1e.
    Anw, thanks for great tutorial, Alex.

  • Prado

    You forgot to #include <vector> in the last quiz question

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter