219

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?

Pierre
  • 1,942
  • 3
  • 23
  • 43
Daniel
  • 2,193
  • 2
  • 9
  • 6
  • 12
    You should use the `override` keyword whenever you are intending to override a method. That way, if you mistype the name in the derived class, you will get an error telling you there was no method found to override – Eric Oct 08 '16 at 12:36
  • 4
    [Is the 'override' keyword just a check for a overriden virtual method?](http://stackoverflow.com/questions/13880205/is-the-override-keyword-just-a-check-for-a-overriden-virtual-method) – Solarflare Oct 08 '16 at 12:37
  • 4
    A more interesting question is "What happens if I use override without virtual" – Eric Oct 08 '16 at 12:39
  • 34
    Why is this marked as a duplicate? It clearly states a different question, and a very good question, in my opinion. This question deals with code style (should `virtual` be left out when `override` is used?), whereas the other question deals with the mechanics of `override`. Anyway, I found the answer to my question here. – Lindydancer Apr 06 '18 at 09:28
  • @Lindydancer Voted to reopen – bobobobo Oct 23 '21 at 16:10

2 Answers2

300

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.

Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 29
    From cppreference (http://en.cppreference.com/w/cpp/language/virtual): "If some member function vf is declared as virtual in a class Base, and some class Derived, which is derived, directly or indirectly, from Base, has a declaration for member function with the same name parameter type list (but not the return type) cv-qualifiers ref-qualifiers Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration) and overrides Base::vf (whether or not the word override is used in its declaration)." – solstice333 Jun 23 '17 at 02:59
  • 2
    so in summay `override` is useless – imbr Nov 20 '19 at 10:42
  • 35
    override is optional and as this answer states helps detects coding mistakes – Superfly Jon Nov 26 '19 at 14:02
  • 23
    @iambr no, override doesn't change the behaviour of a *correct* program, but yells loudly at *incorrect* programs. That is *far* from useless. – Caleth Feb 10 '22 at 09:13
  • Would it still be virtual in the further derived classes if we don't specify the virtual? – Brunisboy Mar 22 '22 at 00:37
  • 1
    @Brunisboy It absolutely would (as long as the original base class doesn't change this). As to derive a class, you need the complete definition of the base class, so (indirectly) including the header with the base class of a hierarchy is inevitable. So all classes deriving from base will “see” the `virtual`. – Wolf Sep 26 '22 at 11:14
  • *"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."* - Why is 'ensuring the function is still virtual' considered to be bad? (I think not using the `virtual` keyword in the derived class(only using `override` if it's not `final`) is a good convention, but I'm asking because I don't get the 'reason' part) – starriet Oct 03 '22 at 04:12
  • 1
    @solstice333, what? override function in derived class can have different return type? won't that be problem? – 23W May 18 '23 at 11:28
  • 2
    @23W The wording allows generally different return types in order to accomodate covariant pointer and reference return types. Other variation is presumably disallowed by some other paragraph, and in any case won't be accepted by a compiler. Covariant pointer and reference works because the size is the same regardless of type, and the covariance is safe (relevant: Liskov substitution principle, LSP). – Cheers and hth. - Alf May 19 '23 at 14:31
52

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 class
  • override: For overrides of that virtual function in a class derived from some base class providing a virtual function of the same (or covariant) signature
  • final: For marking an override as unoverrideable. That is, derivatives of a class with a final 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"); }
};
Edgar Bonet
  • 3,416
  • 15
  • 18
bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • 1
    For newbies like me: This is a *recommendation*, not a part of the language itself. The first link in the answer is good, all newbies should read it :) – starriet Jul 31 '22 at 02:48