Jonathan Boccara's blog

How to Emulate The “super” Keyword In C++

Published December 26, 2017 - 8 Comments

super c++

Daily C++

A derived class sometimes needs to call the code of its base class and name it explicitly.

But for bases classes with a long name, repeating it in the body of the derived class adds a lot of clutter to it. And C++ doesn’t have a super or base keyword to designate “the base class”, like C# and Java do.

One reason for this is that C++ supports multiple inheritance, which would make such a keyword ambiguous. But on the other hand, multiple inheritance is rarely used. So how can a derived class designate its base in the case of single inheritance?

Fortunately there are ways to do this, to make the code of the derived class more expressive.

Repeating the base class’s name?

There are the two situations where a derived class needs to invoke its base’s name.

Calling a constructor of the base class

If a constructor of the derived class needs to call the default constructor of the base type (the one that takes no argument) then no need to write it: the compiler does it for us.

But if the constructor takes some parameters, then we need to call it explicitly:

Calling the implementation of the base class for a virtual method

In theory, you could also need to call the implementation of a non-virtual base class method. But if you have to write the name of the base class to it, it means that you have a non-virtual method of the derived class that has the same name as a non-virtual method of the base class. And as explained in Item 36 of Effective C++, you shouldn’t do that because the derived class would hide the method name of the base class, leading to surprising results.

In C++, virtual functions (and even pure virtual) can have an implementation in the base class, where code can be factored. The above derived class calls this implementation by naming the base class explicitly.

When it becomes a problem

The above cases use short names for the base class. But what if the base class was a template, and located in a nested namespace different from the derived type’s namespace?

Ew. That’s a lot of code, and which doesn’t express anything more that the previous code snippets. It just has the same base name repeated over and over.

This is where we start eyeing the other languages with envy. But not yet! C++ has what we need to remove all that redundant information.

You don’t have to write what the compiler already knows

One of the goals that the language is steering towards is to relieve the developer from the work that the compiler can do on its own. This is well illustrated with the auto keyword in C++11 and template deduction in constructors in C++17.

And even since C++98, the compiler could figure out that when the derived class talks about “Shape“, it is its base class that it means. So the above is exactly equivalent to:

This works unless there is an ambiguity, like if the derived class inherits from two different specializations of the template base class. Or from two classes with the same name but in different namespaces.

But when there isn’t such a alignment of planets as this, using the base class’s name without its template parameters or namespaces works.

Using a typedef

Still, if you want to abstract the name of the base class behind a dedidcated word, such as super or base, this is possible by using a typedef or a using declaration.

One way to go about this is to add the using declaration at the beginning of the derived class (private) section:

But there is another place for the using declaration: in the base class itself. I first saw this in the implementation of the Boost spirit library.

If you opt for doing this, it makes sense to put the declaration in the protected section of the base class. This way, it cannot be mixed up as the base class of the base class itself:

And the derived classes can use base_type in their implementations without having to write a using declaration at their level.

This expresses the message that the class is designed to be inherited from. But the virtual methods already sent this message anyway.

Of course, like the super and base keywords of the other languages, you can only use the using declaration in the base class with single inheritance, otherwise there is an ambiguity in the derived class. But, not unlike Bridget Jones, inheritances are single most of the time anyway (thanks to my brother-in-law Joachim for this astute closing joke).

Share this post! Facebooktwittergoogle_pluslinkedin    Don't want to miss out ? Follow:   twitterlinkedinrss

Receive regular updates to make your code more expressive.