60

For example:

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function() override;
};

From what I read, the override keyword is used to make sure that we have the correct signature in the function that we are overriding, and it seems to be its only use.

However, in the case of a pure virtual function, the compiler would throw an error if we used an incorrect signature in the Derived class (or Base class, depending on how one see things). So, is there any point in adding override at the end of Derived::my_function() declaration?

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
R2B2
  • 1,541
  • 1
  • 12
  • 19
  • 4
    Note that abstractness *propagates*. If you provide the wrong signature in the `Derived` class then the `Derived` class becomes abstract as well. That might not be detected in the correct place without the `override` keyword. – Some programmer dude Sep 27 '17 at 11:25
  • 4
    It ensures that if the base class changes incompatibly with the `override` assertion, your code won't compile. – user207421 Sep 27 '17 at 11:27
  • 1
    "penning purposefully pedagogical programs propagates prefered programming practices" - T.J.Elgan – coderatchet Sep 28 '17 at 03:00
  • Minor benefit to adding it is that some IDEs will use it as the highlight point to show implementations or to jump to the parent. – Craig Taylor Sep 28 '17 at 11:20

4 Answers4

91

However, in the case of a pure virtual function, the compiler would throw an error if we used an incorrect signature in the Derived class

No, this compiles:

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function(int);
//                 ^^^ mistake!
};

While this does not:

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function(int) override;
};

error: void Derived::my_function(int) marked override, but does not override


The error you're talking about only occurs when instantiating Derived - override allows you to catch the mistake earlier and makes the definition of Derived clearer/more readable.

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • You could add in a runtime bug with another class, and implementing `Base::my_function` while leaving it pure virtual. – Yakk - Adam Nevraumont Sep 27 '17 at 13:39
  • 4
    wait so there is a point? You go on to talk about how it is useful but start out with just "no". – Krupip Sep 27 '17 at 15:18
  • 10
    The "No" is in response to the claim that the compiler throws an error. – Sebastian Redl Sep 27 '17 at 15:37
  • Why does that member function definition count as an override in a way that satisfies the compiler? Isn’t the signature not compatible with the base function signature? – templatetypedef Sep 27 '17 at 16:04
  • 1
    @templatetypedef thats the point, a programmer puts override when they believe the signature they are writing should appear exactly in a base class. The first case is a mistake because the programmer intended to override the function, but accidentally wrote an overload instead. – Steve Cox Sep 27 '17 at 17:53
  • @SteveCox Perhaps I'm missing something, but if that's an overload, why would this code compile? Wouldn't the pure virtual function prevent the code from linking? – templatetypedef Sep 27 '17 at 19:01
  • @templatetypedef Compile-time errors are better than link-time errors. – Andre Kostur Sep 27 '17 at 19:29
  • @AndreKostur That's true - but to confirm, you couldn't fully build and run the first bit of code, right? – templatetypedef Sep 27 '17 at 19:31
  • 1
    @templatetypedef I'd rather not wait for the build system to have to work it's way though compiling all of the rest of my project and waiting until it tried to link it all together to only have it finally fail. (Or fail somewhere else when you tried to instantiate a Derived...) It would be much nicer to have it fail when compiling that one file, and have it point to exactly that line and have it say "This line right here is wrong". – Andre Kostur Sep 27 '17 at 20:32
  • @AndreKostur Oh, certainly. I read the part about the code compiling and didn't realize that it meant literally "compiling, but not linking," and was worried I was missing something about the language. – templatetypedef Sep 27 '17 at 21:06
  • Does a *missing* override elicit a compiler warning if the function indeed does override a base class function, possibly unintentionally? That would be another reason to consistently use it: Prevent *accidental* overriding. – Peter - Reinstate Monica Sep 28 '17 at 07:58
  • This could be an especially vile problem if `Base` and `Derived` are part of a library, and `Derived` is only intended for the library's clients but never instantiated by the library itself. In such case, this wouldn't even be a link-time error, but either a test failure or (in absence of testing) a delivered bug. – Angew is no longer proud of SO Sep 28 '17 at 14:02
36

Yes, it is a good idea to use override keyword consistently as a defensive practice.

Consider a redesign when the author of the Base decides that my_function should no longer be a pure virtual, and also that it should take a new parameter. With override in place the compiler will catch this problem; without an override your Derived class would continue to compile.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
11

Yes !!

It improves code clarity: override keyword prevents ambiguity and convey it's meaning of overriding its base class method.

Prevents possible unintended usage: In future, if base class change method signature(here virtual) , it force derive class to change accordingly. (with compiler error). Otherwise(with-out override keyword ) it could be considered method overload, which is not intended.

JharPaat
  • 321
  • 1
  • 2
  • 12
3

Usually not bothering with override just moves an error around. I find the location where you get the error better -- at the point where you define the method that fails to override, instead of when you instantiate the class.

But, there is a way for this to protect against a runtime bug.

struct Base {
  virtual void foo(int x = 0) = 0;

  void foo(double d) {
      foo( (int)d );
  }
};
inline void Base::foo(int x) { std::cout << "Default foo(" << x << ")\n"; }

struct Derived:Base {
  using Base::foo;
  virtual void foo() { // oops, no int!
    std::cout << "Derived::foo()\n";
    Base::foo();
  }
};
struct Derived2:Derived {
  virtual void foo(int x=0) override {
    std::cout << "Derived2::foo()\n";
    Derived::foo(x);
  }
};

here we intend for each foo to call its parent foo. But because Derived::foo doesn't override the same signature as Base::foo, it isn't invoked.

Add override after foo() in Derived and we get a compile time error.

And yes, I implemented the pure virtual function Base::foo.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524