Overriding virtual methods
Overriding virtual functions is one of the most important mechanisms of C++ object oriented programming. The derived class method is overriding base class method when following requirements are met:
- the base class method has virtual keyword,
- derived class method has:
- the same name,
- the same input parameters,
- the same const-ness,
- compatible return type.
If at least one of these requirement is not fulfilled, developer can end with not-overriding method and not even know about it. The C++11 standard introduces specifier override, designed for easy detection of such mistakes.
The simply idea of overriding is that the following code should call print function from Derived class:
This code definitely will work in the intended way, but let’s take a look on a different variations of print method in Derived class. Which one of them – 1, 2 or 3 – will override the print from Base class?
The answer is: none of them!
None of these declarations will allow the method print to be overridden (1 - constness, 2 - inconsistent return type, 3 – inconsistent parameter type). The same thing is if we forget to make print virtual in the Base class. All of these mistakes are easy to do but hard to catch. There are big chances that you will not get any warnings for such implementation. It’s not incorrect – but it probably will not behave the way you wanted.
And here comes C++11 with the new override specifier!
Override in C++11
Just declare methods in Derived class override and the compiler will check for you if there is everything ok with your overriding plans.
You will get here compilation error since print is non-const in Base class.
This is how usage of override specifier provides you more safety and allows you to spot bugs early.
Override equivalent for Qt
Qt is not lagging behind C++ standard. Since Qt5 there is available macro
Q_DECL_OVERRIDE which is equal to
override from C++11.
Usage is also analogous, example:
Besides of override specifier, C++11 introduces also another specifier helpful for working with inheritance: final specifier. This one can be included to function declaration or a class definition when you want to make sure that this method will not be overriden or the class will not be used as a base class.
Usage of final method
Usage is very simple. Just add the specifier
final after method declaration.
Compiler will report an error, because it’s illegal to override final functions.
When to use it?
The introduction of final method into C++11 raises some questions. If somebody doesn’t want to allow to override one function, why did he make it virtual? Wouldn’t be better just to remove virtual keyword from the function in the most base class?
The answer is: no, because it’s not always possible.
Imagine that you own a base class with some virtual methods you want to override. You do so in class Derived; and from this point, the method should not be overriden in any other class. With
final specifier you can prevent the method from overriding starting with any class in hierarchy. It is shown in following example:
The mechanism can be also used by optimization. Calling a virtual function is slower than calling not-virtual function. You can use final method to achieve devirtualization - if you call virtual method from the static object that defined this method as final, the compiler can devirtualize the call and the call has performance of not-virtual method call.
Usage of final class
When a class is not designed to be a base class, add final specifier after its name. The compilation will fail if somebody will try to inherit such class.
When it’s useful?
Some classes are not intended to be inherited from, like std::vector or std::list, classes without virtual destructor or platform dependent classes.
Final specifier is designed for quite specific scenarios. For sure you will not see it very often in the code - the usage is just very particular, in opposite to his sibling
override, which should be used wherever possible.