
- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Input Output Operations
- C++ Basic Input/Output
- C++ Cin
- C++ Cout
- C++ Manipulators
- Type System & Data Representation
- C++ Modifier Types
- C++ Storage Classes
- C++ Constexpr Specifier
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Scope Resolution Operator
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ Jump Statements
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Return Values
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Array Decay
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Destructors
- C++ Virtual Destructor
- C++ Inheritance
- C++ Inheritance
- C++ Multiple Inheritance
- C++ Multilevel Inheritance
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ Override Specifiers
- C++ Final Specifiers
- C++ Design Patterns
- C++ Creational Design Patterns
- C++ Singleton Design Pattern
- C++ Factory Method Design Pattern
- C++ Abstract Factory Pattern
- C++ Prototype Design Pattern
- C++ Structural Design Patterns
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ nullptr
- C++ unordered_multiset
- C++ Structural Design Patterns
- C++ Adapter Pattern
- C++ Bridge Pattern
- C++ Composite Pattern
- C++ Decorator Pattern
Final Specifier in C++
The final specifier was introduced in C++11 with two main purposes −
- The first purpose is to prevent inheritance. When a class is marked with final, other classes can not inherit from it.
- The second purpose it to avoid function overriding. When you mark a virtual function with final, then it can not be overridden in the derived classes.
Read this chapter to learn how to use the final specifier in C++.
Using the final Specifier with Class
You can mark a class as final to prevent inheritance. After marking a class as final, you can no longer use this class for inheritance. Other classes will not be able to inherit them.
The syntax for using final specifier with a class is given below −
class MyClass final { // class members };
Example
Here is an example demonstrating the difference between a class when used with final and when used without final −
In this example, we are using the final specifier with Base class and the Derived class is inheriting the base class. It will give an error in output as shown below −
#include <iostream> using namespace std; class Base final // final class { public: void display(){ cout << "Base class" << endl; } }; // Inheriting from final class class Derived : public Base { public: void show(){ cout << "Derived class" << endl; } }; int main() { Base b; b.display(); return 0; }
The output of the above code is given below −
main.cpp:14:7: error: cannot derive from 'final' base 'Base' in derived type 'Derived' 14 | class Derived : public Base | ^~~~~~~
In this example, we have removed the final specifier from Base class and the Derived class is inheriting the base class. It will not give any error and will work normally −
#include <iostream> using namespace std; class Base // removed final { public: void display(){ cout << "Base class called" << endl; } }; // Inheriting from non-final class class Derived : public Base { public: void show(){ cout << "Derived class called" << endl; } }; int main(){ Base b; b.display(); return 0; }
The output of the above code is as follows −
Base class called
Using the final Specifier with Function
You can mark a function with final to avoid overriding the function. After marking a function as final, you can no longer override that function. The function can only be made final if the function is a virtual function.
The syntax to use final specifier with a function is given below −
class Base { public: virtual void display() final { // implementation } };
Example
The example below demonstrates the difference between a function when used with final and when used without final −
In this example, we have used final specifier on the virtual function breathe() in Mammal class. In the Dog class, we are trying to override the breathe() function which will give an error in the output.
#include <iostream> using namespace std; class Animal { public: virtual void makeSound(){ cout << "Animal sound" << endl; } virtual void breathe(){ cout << "Animal breathing" << endl; } }; class Mammal : public Animal { public: void makeSound() override{ cout << "Mammal sound" << endl; } // final function void breathe() final override { cout << "Mammal breathing" << endl; } }; class Dog : public Mammal{ public: void makeSound() override { cout << "Bark" << endl; } // This would cause an error void breathe() override { cout << "Dog breathing" << endl; } }; int main(){ Dog dog; dog.makeSound(); dog.breathe(); return 0; }
The output of the above code is as follows −
main.cpp:42:10: error: virtual function 'virtual void Dog::breathe()' overriding final function 42 | void breathe() override | ^~~~~~~ main.cpp:27:10: note: overridden function is 'virtual void Mammal::breathe()' 27 | void breathe() final override | ^~~~~~~
In this example, we have removed the final specifier from breathe() function in Mammal class. After overriding the breathe() function in the Dog class it will work normally without any error printing the overridden value in the output.
#include <iostream> using namespace std; class Animal { public: virtual void makeSound(){ cout << "Animal sound" << endl; } virtual void breathe(){ cout << "Animal breathing" << endl; } }; class Mammal : public Animal{ public: void makeSound() override { cout << "Mammal sound" << endl; } // Removed final void breathe() override { cout << "Mammal breathing" << endl; } }; class Dog : public Mammal{ public: void makeSound() override { cout << "Bark" << endl; } // This is safe now void breathe() override { cout << "Dog breathing" << endl; } }; int main(){ Dog dog; dog.makeSound(); dog.breathe(); return 0; }
The output of the above code is as follows −
Bark Dog breathing
Conclusion
The final specifier in C++ helps in preventing the inheritance of classes and the overriding of the virtual function. In this chapter, we explained in detail how the final specifier works with class and virtual function.