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 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 subclassed, 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 whoever 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

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

  • apfelpektin

    readers should consider a donation. this is great work and a lot of energy is being put in it and good books about c++ usually cost good money! the little errors here and there only help in the actual learning process. also this site is now (or soon) up 10 years and still actively improved. thank you.

  • Jonas

    Hello Alex!

    Thank you for this extremely helpful tutorial! I still have a question for a rather weird scenario.

    Consider

    Say I don’t want this derived class to use the function A() (for whatever reasons). Is there a way to use this with the delete specifier?
    I do realize that due to A() being a pure virtual function, the Derived class needs to have a definition for A(). I don’t know if there is ever a
    situation where you would want to do this, but I am just curious if it is even possible.

    Thanks in advance!

    • Alex

      C++ doesn’t provide a way to delete a derived function or make a derived function unusable (this sorta makes sense, after all, Derived is a Base, and if the Base has a property, Derived should too).

  • Anil Gupta

    Wonderful tutorial Alex. I read all the lessons without getting bored. This site contains many tutorials but I  realizes that your tutorial miss one thing and that is :- optimizing a code for performance. It may contain optimizing loops, if-else statements, classes(including constructor, member functions, destructors etc.). Also, the lesson on I/O stream can contain more lessons on working with files.
    But, thanks for such a nice tutorial on C++.

  • Jen

    Alex,

    I very appreciate you post the C++ tutorial, it is an excellent website for self study.
    Do you have other tutorials, such as Java, Object C, iOS or Android ?
    Thank you so much for posting C++ tutorial.

  • Matt

    Under "override":
    "When this happens, it’s can be easy.."

    "it’s" should be "it".

  • sigil

    I’d like to join other readers of this tutorial in congratulating the author on his clear, practical and to-the-point piece of work. These texts and examples make much more sense than what you normally find on the net, or even in books.

  • maxp

    Thanks Alex, I was able to learn a lot.

  • SUDARSHAN KOLAR

    Hi Alex… I really liked your tutorials… It was a fun learning experience… I was wondering do you have a website for python as well? If not, can you please suggest me some? Honestly, I tried looking for Python tutorials from you on google…couldn’t find me…

    Thanks again for such an amazing tutorial… you must be a really good teacher…

    Sudarshan

  • Deondre

    Hey Alex, thanks for taking the time to put together these truly phenomenal tutorials and explanations. I just finished reading through all your lessons (including the featured articles 🙂 ) and I wanted to know what you have planned for the future of this site in terms of new chapters/lessons. If you have any ETA’s for when the new material should be ready that would be great, but if not I understand.

    Thanks again, and hopefully this website can continue to grow and expand as an excellent resource for learning C++.

    • Alex

      I do plan to introduce new material and updates to existing material but I’m a little stalled at the moment due to real-life issues. I’ll get back to it as time permits. Check back periodically -- any new/updated stuff will be noted with a new tag and a date on the front page.

  • ace

    You should add anonymous functions(lambdas) overview, would be nice to learn these.

  • It is 2016, and these tutorials are still helpful. (Loved the way C++11 stuff was added in the appendix.) Thank you Alex for this wonderful resource. Can we also expect lessons on C++14/17 ?

    • Alex

      As I’ve been rewriting the lessons, I’ve been adding in C++11/14 content, so most of the main tutorial is C++11/14 enabled now (and most of the C++11 appendix is redundant). C++14 actually doesn’t contain that much of interest. I’m curious to see what C++17 holds!

  • HattyJetty

    Wow, I’ve managed to get to the end of this wonderful tutorial. I usually get bored very quickly while reading C++ introtuctory stuff, but this source is rather simple and enjoyable, even inspiring. Thanks for your dedicated work! It must be pretty challenging to explain all complexity in such graceful manner. And after nearly 10 years, you still provide all those lessons for free and reply on comments. What a devotion!

  • Ola Sh

    Hello Alex,

    Thanks again for your great tutorials. It made learning C++ easy and fun, something I would not have imagined at first. I will be visiting again for updates and to refresh my knowledge. In the delete section of this lesson, what rule does the compiler follow in converting smaller integral types for the Foo class? Does the compiler apply integral promotion followed by successive numeric promotion, stopping when the new type has a matching constructor? My compiler throws an error stating that more than one constructor matches the argument type. It seems to use integral promotion; however, two constructors with an integral type exist so it throws the error. Thanks for your help. 🙂

    • Alex

      For smaller integral types, the compiler will first try integer promotion, so if your integer constructor is deleted, it will fail. If it can’t find a match, it will try numeric conversion.

Leave a Comment

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