Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use virtual, override, or both keywords?

Tags:

c++

c++11

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?

like image 423
Daniel Avatar asked Oct 10 '22 20:10

Daniel


People also ask

Is it necessary to override a virtual method?

When a method is declared as a virtual method in a base class and that method has the same definition in a derived class then there is no need to override it in the derived class.

What is the use of virtual and override keywords?

So here they are. The Virtual keyword is used for generating a virtual path for its derived classes on implementing method overriding. The Virtual keyword is used within a set with an override keyword.

Is overriding compulsory if virtual keyword used?

They are always defined in the base class and overridden in a derived class. It is not mandatory for the derived class to override (or re-define the virtual function), in that case, the base class version of the function is used.

Can override be done without virtual keyword?

You cannot override a non-virtual or static method. The overridden base method must be virtual , abstract , or override . An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.


2 Answers

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.

like image 268
Cheers and hth. - Alf Avatar answered Oct 22 '22 09:10

Cheers and hth. - Alf


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"); }
};
like image 32
bobobobo Avatar answered Oct 22 '22 10:10

bobobobo