Template inheritance

Introduction

Previously we looked at template class syntax and semantics. In this article we’ll extend this to look at inheritance of template classes.

Inheriting from a template class

It is possible to inherit from a template class.  All the usual rules for inheritance and polymorphism apply.

If we want the new, derived class to be generic it should also be a template class; and pass its template parameter along to the base class.

image

Notice that we ‘pass-down’ the template parameter from the derived class to the base class since there is no class Base, only class Base<T>. The same holds true if we wish to explicitly call a base class method (in this example, the call to Base<T>::set())

We can use this facility to build generic versions of the Class Adapter Pattern – using a derived template class to modify the interface of the base class.

image

Notice, in this case we use private inheritance. This hides the base class methods to any clients (but keeps them accessible to the derived class. Calls to the Adapter’s methods are forwarded on to the base class. For more on the Adapter Pattern see this article.

Extending the derived class

The derived class may itself have template parameters. Please note there must be enough template parameters in the derived class to satisfy the requirements of the base class.

image

Specialising the base class

The derived class may also specialise the base class. In this case we are creating an explicit instance of the base class for all versions of the derived class. That is, all derived class instances, regardless of the type used to instantiate them, will have a base class with a data object of type int.

image

Deriving from a non-template base class

There is no requirement that your base class be a template. It is quite possible to have a template class inherit from a ‘normal’ class.

image

This mechanism is recommended if your template class has a lot of non-template attributes and operations. Instead of putting them in the template class, put them into a non-template base class. This can stop a proliferation of non-template member function code being generated for each template instantiation.

Parameterised inheritance

So far, we have been inheriting explicitly from another (base) class, but there is no reason why we can’t inherit from a template type instead – with the (reasonably obvious) requirement that the template parameter must be a class type. This mechanism allows some neat facilities to be implemented.

In the example below we have built a template class, Named. The class allows a name (string) to be prepended to any class, with the proviso that the base class (the template parameter) supports the member function display().

image

In this example we have constructed a normal class, Waypoint, which supports the display() method (presumably, this displays the current coordinates of the Waypoint; but who knows…).

When we create a Named object, we give it the type of the object we want to ‘decorate’ with a name (in this case, a Waypoint). Calling display() on a Named object will cause it to output the object’s name, before calling display on its base class – in our example Waypoint::display().

(NOTE: I’m quite deliberately ignoring the ‘Elephant in the Room’ with this code – how to generically construct a base class object with a non-default constructor. I’ll revisit this example again in the future when we look at Variadic Templates.)

Summary

This time we’ve covered most of the basic inheritance patterns for templates. Next time we’ll have a look at a practical application for templates in your application code.

Glennan Carnie

Glennan Carnie

Technical Consultant at Feabhas Ltd
Glennan is an embedded systems and software engineer with over 20 years experience, mostly in high-integrity systems for the defence and aerospace industry.

He specialises in C++, UML, software modelling, Systems Engineering and process development.
Glennan Carnie

Latest posts by Glennan Carnie (see all)

Dislike (0)

About Glennan Carnie

Glennan is an embedded systems and software engineer with over 20 years experience, mostly in high-integrity systems for the defence and aerospace industry. He specialises in C++, UML, software modelling, Systems Engineering and process development.
This entry was posted in C/C++ Programming and tagged , , , , , . Bookmark the permalink.

7 Responses to Template inheritance

  1. Dan says:

    Please keep the informative, well-written articles coming. Looking forward to the next post.

    I use this technique a lot, but most of the people I work with are either baffled by this, or say, "You mean you can do that?"

    Also, good use of private inheritance.

    Couple quick notes on the first box (code snippet):

    - I think to "properly" get the expected polymorphic behavior when overriding set() in Derived(), the function should be virtual in Base

    - I think there is a missing semicolon in the definition of "data" for class "Base" (hazard of writing code for PowerPoint, I suspect... I can relate)

    Like (0)
    Dislike (0)
  2. A good article (again) but I don't necessarily agree with this, in the second sentence: "The derived class should be a template class too"

    One reason for inheriting a template class might be to allow the creator of the derived class to configure certain things, at compile time, *without* having to make the derived class, itself, a template. For example, the way to make a task class using a suitable C++ RTOS might be:

    const unsigned int myStackSize = 512;
    class MyTask: public Task
    {
    //---
    };

    [This is a somewhat over-simplified version of a facility offered in Dyagem (an ongoing C++ RTOS project).]

    Like (0)
    Dislike (0)
  3. Unfortunately, your blog's HTML conversion completely removed the template parameter following "Task" in my previous post! There were some angle brackets enclosing the identifier "myStackSize".

    Like (0)
    Dislike (0)
  4. glennan says:

    Oops. A cut-and-paste error left the beginning of this article in a messed-up state. I've edited it to parse properly now.

    Peter,

    I agree, you needn't make the derived class a template class; in fact, this is covered in the section "specialising the base class".

    Like (0)
    Dislike (0)
  5. thanks says:

    Thank you for the article.

    Brief short informative.

    Like (0)
    Dislike (0)
  6. DG says:

    Firstly thank you for this article its extremely informative and to the point.
    I have a question, is it mandatory that the template parameters of both derived and base class match
    eg
    template
    class base
    {
    .....
    };
    template
    class derived:public base
    {
    .....
    };
    Is it okay that the template parameter of base is T and that of derived is s?

    Like (0)
    Dislike (0)

  7. Yep, that's fine; as long as it doesn't render the code confusing the reader 🙂

    Like (0)
    Dislike (0)

Leave a Reply