C++11 and final
One of the lesser known - but still very useful - enhancements to C++11 is
the addition of the final
keyword. This essentially mirrors the final
feature in Java, which has existed since its inception.
The final
keyword in C++11 can be applied to either an entire class or a
method. When applied to a class, it signifies that the class is closed to
derivation; that is, you cannot create a class derived from a final
class.
The second way is when applying final
to a method, which prevents the
method from being overridden by a derived class (though it is still possible
to create subclasses).
How do you declare a final
class?
Given a base class and a derived class, you would normally write:
However, if you wish to prevent the base class from being subclassed, simply
add final
after the classname, thus:
If you try to compile this code, you will get the error:
The compiler specifically prevents any subclassing of Base1
with a hard
error.
How do you declare a final
method?
It is also possible to mark an indvidual method as final
. The method must
be virtual
to begin with, and making it final
prevents it from being
overriden in a derived class.
(If the method isn’t virtual, you would be effectively creating a shadow method that overrides the base method.)
Take the following simple example of a derived class overriding a virtual function declared in the base:
This compiles and works just fine. But if we wanted to ensure that the
method was not reimplmented in any derived classes (For example, to preserve
important behaviour), simply adding the final
modifier at the end of the
method declaration. So given the following example:
the compiler gives us the following error:
Why is final
useful?
Marking a method or entire class as final
could be useful if you need to
prevent client code from modifying the behaviour of your base class. This
may be to enforce ‘contractual’ behaviour (as in Eiffel; not in a legal
sense!), or it may be to prevent resource management problems.
It should be noted that this is in no way a security measure. This is purely a compile-time directive to the compiler to enforce the policy, and has no other effect than to generate an error and stop compiling. In attacking any real-world application, a determined cracker would have any number of mechanisms at their disposal to bypass restrictions that this might impose.
This information about finality can also be exploited by the compiler to optimize code, using a technique known as devirtualisation. If the compiler knows it doesn’t have to use the vtable (virtual method table) to dispatch the method call, it can potentially generate more efficient code.
Sample Code
THe sample code can be otained from:
Final vs Override
In addition to the final
modifier, there is support for expressing the
opposite sense; the override
declaration makes it explicit to the compiler
that you are intentionally overriding a virtual method from a base class.
This is explained in its own article, C++11 and
override.