What is the purpose of the final
keyword in C++11 for functions? I understand it prevents function overriding by derived classes, but if this is the case, then isn't it enough to declare as non-virtual your final
functions? Is there another thing I'm missing here?
What you are missing, as idljarn already mentioned in a comment is that if you are overriding a function from a base class, then you cannot possibly mark it as non-virtual:
struct base {
virtual void f();
};
struct derived : base {
void f() final; // virtual as it overrides base::f
};
struct mostderived : derived {
//void f(); // error: cannot override!
};
virtual
can cause errors, and C++11 added the override
tag to a function that will detect that situation and fail to compile when a function that is meant to override actually hides –
Fluker final
, but if in the code above the static type of the object is base*
then the compiler lacks the required information. Still at runtime there are things that would be done to devirtualize, but not anything that would not be doable without final
. The use case where the static type is the type of the final overrider, well, I am not too sure that will be the common case. –
Fluker It is to prevent a class from being inherited. From Wikipedia:
C++11 also adds the ability to prevent inheriting from classes or simply preventing overriding methods in derived classes. This is done with the special identifier final. For example:
struct Base1 final { }; struct Derived1 : Base1 { }; // ill-formed because the class Base1 // has been marked final
It is also used to mark a virtual function so as to prevent it from being overridden in the derived classes:
struct Base2 { virtual void f() final; }; struct Derived2 : Base2 { void f(); // ill-formed because the virtual function Base2::f has // been marked final };
Wikipedia further makes an interesting point:
Note that neither
override
norfinal
are language keywords. They are technically identifiers; they only gain special meaning when used in those specific contexts. In any other location, they can be valid identifiers.
That means, the following is allowed:
int const final = 0; // ok
int const override = 1; // ok
virtual void f() final
means that it cannot be overridden further. The word further is important, which means depending on final
status, you can and cannot override a virtual function in a class hierarchy like: A -> B -> C -> D -> E
where A
declares f()
to be a virtual function,
B` and C
both override it, as per their need but they do not make it final
, so D
can still override it, but it makes it final
, so E
CANNOT override it, though it can override other virtual functions (if any). Hope that helps. –
Yurikoyursa struct Base2 { virtual void f() final;};
is absurd! –
Ruder class FinalChild final : public Base
to avoid FinalChild
to be extended further. –
Shagbark "final" also allows a compiler optimization to bypass the indirect call:
class IAbstract
{
public:
virtual void DoSomething() = 0;
};
class CDerived : public IAbstract
{
void DoSomething() final { m_x = 1 ; }
void Blah( void ) { DoSomething(); }
};
with "final", the compiler can call CDerived::DoSomething()
directly from within Blah()
, or even inline. Without it, it has to generate an indirect call inside of Blah()
because Blah()
could be called inside a derived class which has overridden DoSomething()
.
Nothing to add to the semantic aspects of "final".
But I'd like to add to chris green's comment that "final" might become a very important compiler optimization technique in the not so distant future. Not only in the simple case he mentioned, but also for more complex real-world class hierarchies which can be "closed" by "final", thus allowing compilers to generate more efficient dispatching code than with the usual vtable approach.
One key disadvantage of vtables is that for any such virtual object (assuming 64-bits on a typical Intel CPU) the pointer alone eats up 25% (8 of 64 bytes) of a cache line. In the kind of applications I enjoy to write, this hurts very badly. (And from my experience it is the #1 argument against C++ from a purist performance point of view, i.e. by C programmers.)
In applications which require extreme performance, which is not so unusual for C++, this might indeed become awesome, not requiring to workaround this problem manually in C style or weird Template juggling.
This technique is known as Devirtualization. A term worth remembering. :-)
There is a great recent speech by Andrei Alexandrescu which pretty well explains how you can workaround such situations today and how "final" might be part of solving similar cases "automatically" in the future (discussed with listeners):
http://channel9.msdn.com/Events/GoingNative/2013/Writing-Quick-Code-in-Cpp-Quickly
final
for de-virtualization optimizations. Check the comments for specific compiler versions that added this feature, and even links to the compiler code. –
Phlebotomize Final cannot be applied to non-virtual functions.
error: only virtual member functions can be marked 'final'
It wouldn't be very meaningful to be able to mark a non-virtual method as 'final'. Given
struct A { void foo(); };
struct B : public A { void foo(); };
A * a = new B;
a -> foo(); // this will call A :: foo anyway, regardless of whether there is a B::foo
a->foo()
will always call A::foo
.
But, if A::foo was virtual
, then B::foo would override it. This might be undesirable, and hence it would make sense to make the virtual function final.
The question is though, why allow final on virtual functions. If you have a deep hierarchy:
struct A { virtual void foo(); };
struct B : public A { virtual void foo(); };
struct C : public B { virtual void foo() final; };
struct D : public C { /* cannot override foo */ };
Then the final
puts a 'floor' on how much overriding can be done. Other classes can extend A and B and override their foo
, but it a class extends C then it is not allowed.
So it probably doesn't make sense to make the 'top-level' foo final
, but it might make sense lower down.
(I think though, there is room to extend the words final and override to non-virtual members. They would have a different meaning though.)
final
. For example, if you know you want all Shape
s to foo()
—something predefined and definite that no derived shape should modify. Or, am I wrong and there's a better pattern to employ for that case? EDIT: Oh, maybe because in that case, one should simply not make the top-level foo()
virtual
to begin with? But still, it can be hidden, even if called correctly (polymorphically) via Shape*
... –
Mic A use-case for the 'final' keyword that I am fond of is as follows:
// This pure abstract interface creates a way
// for unit test suites to stub-out Foo objects
class FooInterface
{
public:
virtual void DoSomething() = 0;
private:
virtual void DoSomethingImpl() = 0;
};
// Implement Non-Virtual Interface Pattern in FooBase using final
// (Alternatively implement the Template Pattern in FooBase using final)
class FooBase : public FooInterface
{
public:
virtual void DoSomething() final { DoFirst(); DoSomethingImpl(); DoLast(); }
private:
virtual void DoSomethingImpl() { /* left for derived classes to customize */ }
void DoFirst(); // no derived customization allowed here
void DoLast(); // no derived customization allowed here either
};
// Feel secure knowing that unit test suites can stub you out at the FooInterface level
// if necessary
// Feel doubly secure knowing that your children cannot violate your Template Pattern
// When DoSomething is called from a FooBase * you know without a doubt that
// DoFirst will execute before DoSomethingImpl, and DoLast will execute after.
class FooDerived : public FooBase
{
private:
virtual void DoSomethingImpl() {/* customize DoSomething at this location */}
};
final
adds an explicit intent to not have your function overridden, and will cause a compiler error should this be violated:
struct A {
virtual int foo(); // #1
};
struct B : A {
int foo();
};
As the code stands, it compiles, and B::foo
overrides A::foo
. B::foo
is also virtual, by the way. However, if we change #1 to virtual int foo() final
, then this is a compiler error, and we are not allowed to override A::foo
any further in derived classes.
Note that this does not allow us to "reopen" a new hierarchy, i.e. there's no way to make B::foo
a new, unrelated function that can be independently at the head of a new virtual hierarchy. Once a function is final, it can never be declared again in any derived class.
The final keyword allows you to declare a virtual method, override it N times, and then mandate that 'this can no longer be overridden'. It would be useful in restricting use of your derived class, so that you can say "I know my super class lets you override this, but if you want to derive from me, you can't!".
struct Foo
{
virtual void DoStuff();
}
struct Bar : public Foo
{
void DoStuff() final;
}
struct Babar : public Bar
{
void DoStuff(); // error!
}
As other posters pointed out, it cannot be applied to non-virtual functions.
One purpose of the final keyword is to prevent accidental overriding of a method. In my example, DoStuff() may have been a helper function that the derived class simply needs to rename to get correct behavior. Without final, the error would not be discovered until testing.
Final keyword in C++ when added to a function, prevents it from being overridden by derived classes. Also when added to a class prevents inheritance of any type. Consider the following example which shows use of final specifier. This program fails in compilation.
#include <iostream>
using namespace std;
class Base
{
public:
virtual void myfun() final
{
cout << "myfun() in Base";
}
};
class Derived : public Base
{
void myfun()
{
cout << "myfun() in Derived\n";
}
};
int main()
{
Derived d;
Base &b = d;
b.myfun();
return 0;
}
Also:
#include <iostream>
class Base final
{
};
class Derived : public Base
{
};
int main()
{
Derived d;
return 0;
}
virtual void myfun() final
in base class is apparently meaningless. –
Ruder Final keyword have the following purposes in C++
- If you make a
virtual
method in base class asfinal
, it cannot be overridden in the derived class. It will show a compilation error:
class Base {
public:
virtual void display() final {
cout << "from base" << endl;
}
};
class Child : public Base {
public:
void display() {
cout << "from child" << endl;
}
};
int main() {
Base *b = new Child();
b->display();
cin.get();
return 0;
}
- If we make a class as
final
, it cannot be inherited by its child classes:
class Base final {
public:
void displayBase() {
cout << "from base" << endl;
}
};
class Child :public Base {
public:
void displayChild() {
cout << "from child" << endl;
}
};
Note: the main difference with final
keyword in Java is ,
a) final
is not actually a keyword in C++.
you can have a variable named as final
in C++
b) In Java, final
keyword is always added before the class
keyword.
Supplement to Mario Knezović 's answer:
class IA
{
public:
virtual int getNum() const = 0;
};
class BaseA : public IA
{
public:
inline virtual int getNum() const final {return ...};
};
class ImplA : public BaseA {...};
IA* pa = ...;
...
ImplA* impla = static_cast<ImplA*>(pa);
//the following line should cause compiler to use the inlined function BaseA::getNum(),
//instead of dynamic binding (via vtable or something).
//any class/subclass of BaseA will benefit from it
int n = impla->getNum();
The above code shows the theory, but not actually tested on real compilers. Much appreciated if anyone paste a disassembled output.
There is also a non-trivial example, related to calling virtual functions from CTORs:
class Base
{
virtual void func() = 0;
public:
virtual ~Base() {}
};
class Derived : public Base
{
void func() override {}
public:
Derived() { func(); }
};
This calls a virtual function from a CTOR, which is well defined but often seen dangerous. If you now inherit from Derived
, a further overridden func
will not be called in the Derived
CTOR.
In QtCreator, I got this clang-analyzer warning:
virt.cpp:12:17: Call to virtual method 'Derived::func' during construction bypasses virtual dispatch [clang-analyzer-optin.cplusplus.VirtualCall]
However, the warning makes only sense if I ever intend to inherit from Derived
. Since I did not, rewriting Derived
as class Derived final
(or, since the OP asks for it, adding final
to the function declaration) silenced this warning for me.
© 2022 - 2025 — McMap. All rights reserved.
virtual
keyword or not. – Frailfinal
usage, prevents function overriding by derived classes. Suppose, I have functionvoid func(int);
in base class. Iffinal
prevents from overriding so the derived class can use different arguments list forfunc
? eg.void func(int, int) final;
in the derived class? But this doesn't work. Compiler shows an error that you can't change arguments list. – Importfunc
is not virtual, so there is nothing to override and thus nothing to mark asoverride
orfinal
. – Frailauto final = 10; std::cout << final;
is perfectly valid albeit, horribly written code. – Luht