In object-oriented programming, virtual functions are object methods that are inheritable and overridable. This allows derived classes to access the member data/functions of a base object, if they aren’t re-implemented in the derived class. Another key mechanism is the overridability, where we can re-implement our own version of the virtual function in the derived class.
One use-case is if we have assign a derived class object to a base class pointer, in a process called upcasting.
This base class can only directly access members declared in the base class. However, if they’re virtual functions, we can correctly call the derived class’ implementation instead of the base class.
Non-virtual functions are invoked depending on the type of pointer, which is known at compile-time. Virtual functions are invoked depending on the type the pointer points to, known at run-time (dynamic dispatch).
A class that inherits a virtual function is called a polymorphic class.
Defining
When we define virtual functions, our function signature looks like:
Objects of the base class may sometimes never be intended to be instantiated and only serve to derive other classes. We can enforce pure virtual methods that don’t have a definition by default, so any derived class should re-define.
A class with one or more pure virtual functions is called an abstract class, because objects of these classes cannot be instantiated. They’re also sometimes called interfaces, because they force derived classes to define the virtual function they inherit.
In a derived class, we can also define a virtual function (or class) implementation that can’t be overridden in further derived classes:
We can disable virtual function dispatch (i.e., keep a function local to a class) with the static
keyword:
We can also set a default implementation of a virtual function:
Overriding
We can override a function by defining a function with the same function signature. We don’t need to use virtual
again, since it’s inherited from the base class, but we can if we want. To specify that we’re overriding a virtual function, we should use the override
keyword.
This keyword ensures that the compiler knows we’re strictly overriding a virtual function. If the virtual function in the base class doesn’t exist, then it’ll cause a compile-time error.
This is useful if we remove the
virtual
function later down the line in the base class. It’s an extra step for us to ensure our code’s intentions don’t break.
If we don’t want to use a virtual function, we can delete it and prevent its use: