Note that non-inheritable classes exist in C++11 using the final keyword, specified before the : base1, base2, ..., baseN inheritance list or before the opening { if the class inherits from nothing:

class Final final { };
class Derived : public Final { }; // ERROR

With a little macro magic and some compiler-detection effort this can be abstracted away to work, or at worst do nothing, on all compilers.

Answer from Jeff Walden on Stack Overflow
🌐
Cppreference
en.cppreference.com › w › cpp › language › final.html
final specifier (since C++11) - cppreference.com
Specifies that a virtual function cannot be overridden in a derived class, or that a class cannot be derived from. When applied to a member function, the identifier final appears immediately after the declarator in the syntax of a member function declaration or a member function definition ...
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › c-final-specifier
C++ final Specifier - GeeksforGeeks
July 23, 2025 - Note that use of final specifier in C++ 11 is same as in Java but Java uses final before the class name while final specifier is used after the class name in C++ 11.
Top answer
1 of 7
33

Note that non-inheritable classes exist in C++11 using the final keyword, specified before the : base1, base2, ..., baseN inheritance list or before the opening { if the class inherits from nothing:

class Final final { };
class Derived : public Final { }; // ERROR

With a little macro magic and some compiler-detection effort this can be abstracted away to work, or at worst do nothing, on all compilers.

2 of 7
11

Well, for this program (pleasse provide correct, compilable examples)

#include <iostream>

class Temp
{
private:
    ~Temp() {}
    friend class Final;
};

class Final : virtual public Temp
{
public:
    void fun() { std::cout<<"In base"; }
};

class Derived : public Final {};

int main() {
    Derived obj;
    obj.fun();
}

Comeau Online says

Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 16: error: "Temp::~Temp()" (declared at line 6) is inaccessible
  class Derived : public Final {
                         ^
          detected during implicit generation of "Derived::Derived()" at line
                    21

"ComeauTest.c", line 16: error: "Temp::~Temp()" (declared at line 6) is inaccessible
  class Derived : public Final {
        ^
          detected during implicit generation of "Derived::~Derived()" at line
                    21

2 errors detected in the compilation of "ComeauTest.c".

Since, when in doubt, I always trust como (I have only ever found one error in it, but many in other compilers), I suppose VC9 (which accepts the code) is in error. (From that void main() I suppose you use VC, too.)

🌐
Checkstyle
checkstyle.sourceforge.io › checks › design › finalclass.html
FinalClass – checkstyle
public class Example1 { // ok, since it has a public constructor final class A { private A() { } } class B { // violation, 'Class B should be declared as final.' private B() { } } class C { // ok, since it has a public constructor int field1; String field2; private C(int value) { this.field1 = value; this.field2 = " "; } public C(String value) { this.field2 = value; this.field1 = 0; } } class AnonymousInner { // ok, class has an anonymous inner class.
Top answer
1 of 3
21

The reason I am asking this is because final functions become qualified for de-virtualization, which is a great optimization.

Do they? "De-virtualization" is not part of the C++ standard. Or at least, not really.

De-virtualization is merely a consequence of the "as if" rule, which states that the implementation can do whatever it likes so long as the implementation behaves "as if" it is doing what the standard says.

If the compiler can detect at compile-time that a particular call to a virtual member function, through a polymorphic type, will undeniably call a specific version of that function, then it is allowed to avoid using the virtual dispatching logic and calling the function statically. That's behaving "as if" it had used the virtual dispatching logic, since the compiler can prove that this is the function that would have been called.

As such, the standard does not define when de-virtualization is allowed/forbidden. A compiler, upon inlining a function that takes a pointer to a base class type, may find that the pointer being passed is pointing to a stack variable local declared in the function that it is being inlined within. Or that the compiler can trace down a particular inline/call graph to the point of origin for a particular polymorphic pointer/reference. In those cases, the compiler can de-virtualize calls into that type. But only if it's smart enough to do so.

Will a compiler devirtualize all virtual function calls to a final class, regardless of whether those methods are declared final themselves? It may. It may not. It may not even devirtualize any calls to methods declared final on the polymorphic type. That's a valid (if not particularly bright) implementation.

The question you're asking is implementation specific. It can vary from compiler to compiler.

However, a class being declared final, as you pointed out, ought to be sufficient information for the compiler to devirtualize all calls to pointers/references to the final class type. If a compiler doesn't do so, then that's a quality-of-implementation issue, not a standards one.

2 of 3
8

To quote the draft C++ standard from here [class.virtual/4]:

If a virtual function f in some class B is marked with the virt-specifier final and in a class D derived from B a function D::f overrides B::f, the program is ill-formed.

And here [class/3]:

If a class is marked with the class-virt-specifier final and it appears as a base-type-specifier in a base-clause (Clause [class.derived]), the program is ill-formed.

So, in answer to the question;

Does a final class implicitly imply its virtual functions to be final as well? Should it? Please clarify.

So, at least not formally. Any attempt to violate either rule will have the same result in both cases; the program is ill-formed and won't compile. A final class means the class cannot be derived from, so as a consequence of this, its virtual methods cannot be overridden.

Should it? At least formally, probably not; they are related but they are not the same thing. There is also no need formally require the one to imply the other, the effect follows naturally. Any violations have the same result, a failed compilation (hopefully with appropriate error messages to distinguish the two).


To touch on your motivation for the query and the de-virtualization of the virtual calls. This is not always immediately affected by the final of the class nor method (albeit they offer help), the normal rules of the virtual functions and class hierarchy apply.

If the compiler can determine that at runtime a particular method will always be called (e.g. with an automatic object, i.e. "on the stack"), it could apply such an optimisation anyway, irrespective of the method being marked final or not. These optimisations fall under the "as-if" rule, that allow the compiler to apply any transformation so long as the observable behaviour is as-if the original code had been executed.

Top answer
1 of 7
962

The final keyword has several usages in Java. It corresponds to both the sealed and readonly keywords in C#, depending on the context in which it is used.

Classes

To prevent subclassing (inheritance from the defined class):

Java

public final class MyFinalClass {...}

C#

public sealed class MyFinalClass {...}

Methods

Prevent overriding of a virtual method.

Java

public class MyClass
{
    public final void myFinalMethod() {...}
}

C#

public class MyClass : MyBaseClass
{
    public sealed override void MyFinalMethod() {...}
}

As Joachim Sauer points out, a notable difference between the two languages here is that Java by default marks all non-static methods as virtual, whereas C# marks them as sealed. Hence, you only need to use the sealed keyword in C# if you want to stop further overriding of a method that has been explicitly marked virtual in the base class.

Variables

To only allow a variable to be assigned once:

Java

public final double pi = 3.14; // essentially a constant

C#

public readonly double pi = 3.14; // essentially a constant

As a side note, the effect of the readonly keyword differs from that of the const keyword in that the readonly expression is evaluated at runtime rather than compile-time, hence allowing arbitrary expressions.

2 of 7
230

It depends on the context.

  • For a final class or method, the C# equivalent is sealed.
  • For a final field, the C# equivalent is readonly.
  • For a final local variable or method parameter, there's no direct C# equivalent.
Find elsewhere
🌐
Wikibooks
en.wikibooks.org › wiki › More_C++_Idioms › Final_Class
More C++ Idioms/Final Class - Wikibooks, open books for an open world
Final class idiom makes use of virtual inheritance and a friend class to create the effect of a final class. The idiom depends on the following C++ rule: the constructor (and destructor) of a virtually inherited class is called directly by the derived-most class.
🌐
TutorialsPoint
tutorialspoint.com › simulating-final-class-in-cplusplus
Simulating final class in C++
#include <iostream> using namespace std; class MyClass; class MakeFinalClass { private: MakeFinalClass() { cout << "This is constructor of the MakeFinalClass" << endl; } friend class MyClass; }; class MyClass : virtual MakeFinalClass { //this will be final class public: MyClass() { cout << "This is constructor of the final Class" << endl; } }; //try to make derived class class MyDerivedClass : MyClass { public: MyDerivedClass() { cout << "Constructor of the Derived Class" << endl; } }; main() { MyDerivedClass derived; }
🌐
Microsoft Learn
learn.microsoft.com › en-us › cpp › cpp › final-specifier
final Specifier | Microsoft Learn
You can also use it to designate classes that cannot be inherited. function-declaration final; class class-name final base-classes
🌐
Reddit
reddit.com › r/cpp › the performance impact of c++'s `final` keyword.
r/cpp on Reddit: The Performance Impact of C++'s `final` keyword.
April 22, 2024 - Could be interesting to rerun with contemporary compilers to see how/if things have changed. ... I've taken about two readthroughs of the article. I'm planning on writing a follow up myself and want to mention your previous work. I'm having some trouble interpreting your results; It's there a clear metric of "with final and without final"? ... Where "f" stands for final. What the results show is: There doesn't seem to be much difference between invoking a function on a derived class or a final derived class through a base pointer, even in the cases where the compiler can in principle know that the objects are really of derived type (an not of a further derived class from that).
Top answer
1 of 2
31

As the implementer of GCC's __is_final intrinisic (for PR 51365) I'm pretty sure it can't be done in a library, it needs compiler support.

You can do some very clever things with C++11's SFINAE for expressions feature but to detect whether a class is final you'd need to derive from it, and instantiate the derived type, in a template argument deduction context, but deriving from a class is done in a declaration not an expression.

Also, you should think about whether you only want to know if the final pseudo-keyword was used, or if a class is un-derivable for other reasons, such as having only private constructors.

2 of 2
12

Type traits are usually implemented using the SFINAE idiom, which places a potentially ill-formed expression inside a function template declaration. Substituting the typename in question into the declaration results in an error, but the error is suppressed in that context, so the declaration is either used or not. But a fallback overload backs up the potentially missing declaration. Another bit of code accesses the function to detect whether the sensitive overload or only the backup was instantiated.

This won't work for final because it can only cause failure during template instantiation of a class. There's no way to overload classes, and no way to tentatively define a class that will fail but not halt compilation in case it's derived from final.

Standard quote, C++11 §14.8.2/8:

Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [ Note: The evaluation of the substituted types and expressions can result in side effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such side effects are not in the “immediate context” and can result in the program being ill-formed. — end note ]

🌐
Microsoft
devblogs.microsoft.com › dev blogs › c++ team blog › the performance benefits of final classes
The Performance Benefits of Final Classes - C++ Team Blog
March 2, 2020 - The final specifier is useful for expressing to readers of the code that a class is not to be derived from and having the compiler enforce this, but it can also improve performance through aiding devirtualization.
🌐
Cplusplus
cplusplus.com › forum › beginner › 223951
Final Keyword - C++ Forum
should I put it after every class I make if it wont be inherited from, or only use it in special cases, and if so, what are some special use cases? ... final is not a keyword; it is a specifier.
🌐
TutorialsPoint
tutorialspoint.com › What-are-final-classes-in-Java
What are final classes in Java?
The final modifier for finalizing the implementations of classes, methods, and variables. The main purpose of using a class being declared as final is to prevent the class from being subclassed. If a class is marked as final then no class c
🌐
John Farrier
johnfarrier.com › home › the definitive guide to the c++ final keyword
The Definitive Guide to the C++ final Keyword - John Farrier
July 1, 2025 - Preventing Class Inheritance: Marking a class as final stops it from being used as a base class. Preventing Virtual Function Overriding: When applied to a virtual function, it ensures that no derived class can override that function.
🌐
cppast
foonathan.net › 2016 › 05 › final
You (probably) don't want `final` classes
Because the function must be virtual so the only way you can use final then is if you write: virtual void foo() final; in the base class. You make a function virtual but at the same time final so it cannot be overridden. I hope we all agree why this doesn’t make sense.
🌐
Javatpoint
javatpoint.com › final-keyword
final keyword - javatpoint
final keyword. The final is a keyword in java. Final can be variable, method, class or parameter. Let's see what are there usage.
Top answer
1 of 1
7

Whenever you don't want the class to be extended. Designing for extension has a cost (see also Eric Lippert's Blog: Why Are So Many Of The Framework Classes Sealed?) - you need to make sure you provide the right hooks for the class, that people can implement those hooks without breaking things, that you can be reasonably sure that subclasses won't be nefarious (this is especially important with core language classes like String and Integer), that the contracts that the superclasses implement are clear (so that subclasses don't break them easily).

This takes work, time, and thought to put into it. It isn't easy developing a class that is meant to be extended. And sometimes, you know you don't want it to be extended - that it can be put to nefarious use and cause havoc with your implementation if someone passes you a mutable String rather than an immutable one.

And so, you make the classes final. There can be no mutable String, because its an immutable class and its final. You know when you get it, it won't be changed from under you in some way. You can save it and be sure that that it will behave like a String, always - no subclasses can be made to make it be otherwise.

Thus, there is a bit of design that some follow that all classes start out as default to be final. How often are you going to subclass that DTO? And when you do want to subclass it for some reason, you should spend some time thinking about the implications of removing the modifier.

There is a check style rule Design For Extension. Personally, I like it. In every non-final class, every method must be one of:

  • abstract
  • final
  • empty implementation

This sort of thinking then allows you to write subclasses that are clearly implemented the proper way - providing hooks and preventing the superclass fro being broken by the subclass not knowing about tinkering the innards of it in an unexpected way. Though, admittedly, this design philosophy means that the subclasses are more limited in their flexibility - but they can't corrupt the state of their superclass.

Again, if you're not prepared or willing to design a class so that it can be extended cleanly, it is best to design the class so it can't be extended at all.