Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A final class in C++ is a class that cannot be inherited by any other class. Introduced in C++11, the final specifier is a context-sensitive keyword placed immediately after the class name in the class declaration, instructing the compiler to reject any attempt to use the class as a base class.

Syntax

The final specifier appears after the class identifier and before any base-clause (if the class itself inherits from another class).
// A standalone final class
class TerminalClass final {
    // Class members
};

class BaseClass {};

// A final class that inherits from a base class
class DerivedTerminalClass final : public BaseClass {
    // Class members
};

Compiler Behavior

Enforcement of the final specifier occurs strictly at compile time. If a developer attempts to define a struct or class that derives from a final class, the compiler will halt compilation and emit an error.
class SealedClass final {};

// COMPILE-TIME ERROR: cannot derive from 'final' base 'SealedClass'
class InvalidDerivedClass : public SealedClass {}; 

Context-Sensitive Keyword

Unlike strict reserved keywords (such as class, int, or return), final is a context-sensitive identifier. It only carries special meaning when placed in the specific syntactic position of a class declaration (or a virtual function declaration). In all other contexts, final can still be used as a standard identifier without causing syntax errors.
class ValidClass final {
public:
    // Valid: 'final' is used as a member variable name
    int final = 42; 
    
    // Valid: 'final' is used as a parameter name
    void process(bool final) const {
        if (final) {
            // Execution logic
        }
    } 
};

Interaction with Virtual Functions

When a class is marked final, it inherently terminates the polymorphic chain. Because no class can derive from a final class, it is impossible for any virtual functions declared within it to be overridden further down an inheritance hierarchy.
class Base {
public:
    virtual void doWork() {}
};

class Leaf final : public Base {
public:
    // Overrides Base::doWork. 
    // Cannot be overridden further because 'Leaf' cannot be inherited.
    void doWork() override {} 
};

Devirtualization (Static Binding)

A critical mechanical advantage of final classes is devirtualization. Because the compiler guarantees that a final class cannot be subclassed, it possesses absolute certainty about the dynamic type of the object. When a virtual method is called on a pointer or reference whose static type is a final class, the compiler can safely bypass the virtual method table (vtable) lookup at runtime. Instead, it resolves the method call at compile time (static binding). This eliminates the overhead of dynamic dispatch and allows the compiler to apply aggressive optimizations, such as function inlining.
class Base {
public:
    virtual void compute() {}
};

class OptimizedClass final : public Base {
public:
    void compute() override {}
};

void execute(OptimizedClass& obj) {
    // The compiler knows 'obj' cannot be a derived type.
    // The virtual call is devirtualized and resolved statically.
    obj.compute(); 
}

Type Traits Integration

The C++ Standard Library provides a type trait in the <type_traits> header to query whether a class is marked final at compile time. std::is_final<T>::value (or the C++17 variable template std::is_final_v<T>) evaluates to true if T is a final class type.
#include <type_traits>

class NormalClass {};
class FinalClass final {};

static_assert(!std::is_final_v<NormalClass>, "NormalClass is not final");
static_assert(std::is_final_v<FinalClass>, "FinalClass is final");
Master C++ with Deep Grasping Methodology!Learn More