Search

B.6 — New virtual function controls: override, final, default, and delete

override

When working with derived classes, it’s fairly easy to inadvertently create a new virtual function in the derived class when you actually meant to override a function in the base class. This happens when you fail to properly match the function prototype in the derived class with the one in the base class. For example:

When this happens, it’s can be easy to make a function call to A() or B() and expect to get the derived version but end up getting the base version instead.

This phenomena can also easily occur when you add a new parameter to a function in Base but forget to update the version in Derived. When that happens, the function that was an override in Derived is no longer an override, and your code mysteriously stops working. These kinds of problems can be hard to find because the change that triggers them is so innocuous looking.

C++11 introduces a new identifier called override that allows you to explicitly mark functions you intend to be overrides. If the function is not an override, the compiler will complain about it. For example:

Although use of the override identifier is not required, it is highly recommended, as it will help prevent inadvertent errors.

(If you’re wondering why this was implemented as an identifier rather than a keyword, I presume this was done so that the name “override” can be used as a normal variable name in other contexts. If it had been defined as a keyword, it would be reserved in all contexts, which might break existing applications)

final

There are occasionally times when you don’t want to allow someone to override a virtual function, or even create a derived class. C++11 adds the identifier final to provide this functionality.

The following example shows the use of the final identifier to make a function non-overrideable:

The final identifier can also be used on classes to make them non-inheritable:

There are some legitimate reasons to make functions or classes final. For example, the most common use of final is to ensure that an immutable class stays immutable. An immutable class is a specially-designed class whose state cannot be modified after it is created. Without the final identifier, a derived class could add functions that could cause the class to become mutable. If the base class is made final, it cannot be subclasses, and this is avoided.

However, generally speaking, unless you have a really good reason, use of final should generally be avoided. And if you do use the final keyword, document why, as it will likely not be obvious to whomever inherits your code.

default

By default, C++ will provide a default constructor, copy constructor, copy assignment operator (operator=) and a destructor. If you provide alternate versions of any of these functions for your class, C++ will not provide a default version. However, in C++11, you can now specify that you would like the compiler to provide a default one anyway. This is done by prototyping the function and using the default specifier:

The default specifier can only be used with functions that have a default.

delete

More useful than the default specifier is the delete specifier, which can be used to disallow a function from being defined or called. One of the best uses of the delete specifier is to make a class uncopyable:

The delete specifier can also be used to make sure member functions with particular parameters aren’t called. For example:

In the above example, if you try to call Foo with a char, short, int, or long, those will all get implicitly converted to a long, which will then match Foo(long). Since Foo(long) has been deleted, the compiler will error.

If you want your class to only be called with very specific data types, you can turn off implicit conversions altogether by using a templated function to match everything that isn’t defined explicitly:

Index
B.5 -- Delegating constructors

59 comments to B.6 — New virtual function controls: override, final, default, and delete

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">