Should I use virtual, override, or both keywords?
C++C++11C++ Problem Overview
In the last weeks something is bugging my brain about virtual
and override
.
I've learned that when you do inheritance with virtual function you have to add virtual
to let the compiler know to search for the right function.
Afterwards I learned also that in c++ 11 there is a new keyword - override
. Now I'm a little confused; Do i need to use both virtual and override keywords in my program, or it's better to use only one of them?
To explain myself - code examples of what I mean:
class Base
{
public:
virtual void print() const = 0;
virtual void printthat() const = 0;
virtual void printit() const = 0;
};
class inhert : public Base
{
public:
// only virtual keyword for overriding.
virtual void print() const {}
// only override keyword for overriding.
void printthat() const override {}
// using both virtual and override keywords for overriding.
virtual void printit() const override {}
};
What is the best method?
C++ Solutions
Solution 1 - C++
When you override a function you don't technically need to write either virtual
or override
.
The original base class declaration needs the keyword virtual
to mark it as virtual.
In the derived class the function is virtual by way of having the ¹same type as the base class function.
However, an override
can help avoid bugs by producing a compilation error when the intended override isn't technically an override. For instance, the function type isn't exactly like the base class function. Or that a maintenance of the base class changes that function's type, e.g. adding a defaulted argument.
In the same way, a virtual
keyword in the derived class can make such a bug more subtle by ensuring that the function is still virtual in the further derived classes.
So the general advice is,
-
Use
virtual
for the base class function declaration.
This is technically necessary. -
Use
override
(only) for a derived class' override.
This helps maintenance.
Example:
struct Base { virtual void foo() {} };
struct Derived: Base { void foo() override {} };
Notes:
¹ C++ supports covariant raw pointer and raw reference results. With covariance the type of the override isn't exactly the same. It just has a compatible type.
Solution 2 - C++
According to the C++ Core Guidelines C.128, each virtual function declaration should specify exactly one of virtual
, override
, or final
.
virtual
: For the "first" appearance of a function in the base classoverride
: For overrides of thatvirtual
function in a class derived from some base class providing avirtual
function of the same (or covariant) signaturefinal
: For marking an override as unoverrideable. That is, derivatives of a class with afinal
virtual function override cannot have that virtual function override overridden.
struct A {
virtual void go() { puts("A"); }
};
struct B : A {
// Overrides A::go(). No need to specify `virtual` explicitly,
// it already implicitly is virtual and overrideable
void go() override { puts("B"); }
};
struct C : B {
void go() final { puts("C"); }
//virtual void go() override final { puts("C"); } would still compile,
// but it is considered, for lack of a better description, "extra"
};
struct D : C {
// Would produce error C3248 : 'C::go' : function declared as 'final' cannot be overridden by 'D::go'
//void go() override { puts("D"); }
};