4

Background

I just stumbled over a use case of the override specifier that, as far as I can tell, seems redundant and also without any particular semantics meaning, but maybe I'm missing something, hence this question. Before proceeding, I should point out that I've tried to find an answer to it here on SO, but the nearest I got were the following threads, not really answering my query (maybe someone can point out a Q&A that actually already answers my question).

Question

Consider the following abstract class:

struct Abstract {
  virtual ~Abstract() {};
  virtual void foo() = 0;
};

Is there any reason to use the override specifier when implementing foo() in a non-abstract class derived directly from Abstract (as in DerivedB below)? I.e., when the implementation of foo() is already required for the derived class to be non-abstract (and not really overriding anything)?

/* "common" derived class implementation, in my personal experience
   (include virtual keyword for semantics) */
struct DerivedA : public Abstract {
  virtual void foo() { std::cout << "A foo" << std::endl; }
};

/* is there any reason for having the override specifier here? */
struct DerivedB : public Abstract {
  virtual void foo() override { std::cout << "B foo" << std::endl; }
};
Community
  • 1
  • 1
dfrib
  • 70,367
  • 12
  • 127
  • 192
  • 1) It helps in figuring out which methods are derived. 2) Possibly it can help compiler with some optimisations It is the same as in java (@override) – Krzysztof Bargieł Sep 07 '16 at 12:53
  • 2
    It is a nice catch in case you change the signature in the base but forget to update the derived. – NathanOliver Sep 07 '16 at 12:55
  • 1
    You don't technically need `virtual` in the subclass either, yet you use it. `override` is just better in that it more clearly conveys the intent. – Sebastian Redl Sep 07 '16 at 12:55
  • @KrzysztofBargieł: "help" how? The compiler surely knows that that function is an override. `override` is for the humans. – peppe Sep 07 '16 at 12:55
  • @peppe there are reasons for override being implementes. If you change the signature in the base class (on a non-pure virtual function) everythign still compiles and you don't get any errors without override. – Hayt Sep 07 '16 at 13:00
  • @Hayt: what I mean is that whether a function is overriding or not is *not* determined by the presence of the `override` keyword. That's a development aid, not a help for the compiler. – peppe Sep 07 '16 at 13:02
  • It is a helper for the compiler to know whether this function is intended to override something or not and generate an error if needed. – Hayt Sep 07 '16 at 13:05
  • @SebastianRedl, Hayt, ...: thanks for the contributions in the discussion above; `override` in this context clearly holds some merit w.r.t. semantics and maintanability. – dfrib Sep 07 '16 at 13:34

4 Answers4

9

I'm not a big fan of override, but, assuming it's something that you find useful in general, then, yes, putting override on a virtual function that overrides a pure virtual functions is useful. Consider this rather contrived example:

struct Base {
    virtual void f() = 0;
};

struct Derived : Base {
    virtual void f();
    virtual void f(int);
};

Now suppose that the maintainer of Base (perhaps even your future self) changes Base to look like this:

struct Base {
    virtual void f(int) = 0;
};

Now the behavior of Derived has quietly changed. With override the compiler would report an error.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
3

Technically, both versions are syntactically correct and legal. The override specifier is mainly meant to prevent unexpected behavior. The compiler will throw an error as soon as it encounters a member function marked as override which is not actually overriding a virtual function. This may occur if, for some reason, you change the signature of the virtual base class function. Consider this example:

class Abstract {
    virtual void foo() { ...}
}; 

class Derived : public Abstract {
    void foo() override { ... }
};

Now, if the signature of Abstract::foo is changed, let's say to

class Abstract {
    virtual void foo(int bar) { ...}
}; 

the compiler will throw an error at Derived::foo as it no longer overrides a function of Abstract which it wouldn't without the override qualifier. This helps you to better maintain your code. However, in your specific case (i.e. with pure virtual declarations), an error would be thrown as well. So using override is mainly considered "good practice", I guess. More on that topic: http://en.cppreference.com/w/cpp/language/override

Felix Lauer
  • 201
  • 1
  • 10
2

In case of pure virtual functions and compilations not really. You will get an error anyway (except in as in the example from Pete)

But the error message may be more readable if you get an error like "your function does not override anything" compared to later "cannot instantiate abstract class"

Another advantage would be while reading the declaration you know this is a derived method from a base class.

Also it is good practice to just get used to declare all overridden methods with override. So why make a difference here and have inconsistent style.

As to why it is good to have all overriden methods be declared override:

imagine you have

class A
{
    virtual void Foo();
};

class B: public A
{
    virtual void Foo() override;
};

And then you change Foo to a const function in A. Without override this will compile but when you call A->foo() and it is a B object B->foo() will not be called without any indication something changed there. With override you get an error here.

Hayt
  • 5,210
  • 30
  • 37
1

The main advantage of override here would be to encourage maintainability. Consider below:

class Foo
{
public: 
    virtual void foo() = 0;
};
class Derived : public Foo
{
public:
    //....
    virtual void foo(double x) override
    {
         //This throws error
    }
};

As you can see above, the compiler would throw an error if you compiled the above. What would happen is the compiler would complain about the function not having the same signature. Without the override keyword, the outcome would have differed.

Arnav Borborah
  • 11,357
  • 8
  • 43
  • 88