Is the 'Override' Keyword Just a Check For a Overridden Virtual Method

Is the 'override' keyword just a check for a overridden virtual method?

That's indeed the idea. The point is that you are explicit about what you mean, so that an otherwise silent error can be diagnosed:

struct Base
{
virtual int foo() const;
};

struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};

The above code compiles, but is not what you may have meant (note the missing const). If you said instead, virtual int foo() override, then you would get a compiler error that your function is not in fact overriding anything.

Should I use virtual, override, or both keywords?

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.

C++ override specifier without virtual? Does override imply virtual?

The answer you're looking for is in https://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).

Can i override non virtual function in c++

You do not override say in B

from C++ override specifier :

In a member function declaration or definition, override ensures that the function is virtual and is overriding a virtual function from a base class. The program is ill-formed (a compile-time error is generated) if this is not true.

Look at that example :

#include <iostream>

class A
{
public:
void say()
{
std::cout << "From A\n";
}
};

class B : public A {
public:
void say()
//override
{
std::cout << "From B\n";
}
};

int main()
{
A a;
B b;

a.say();
b.say();
((A &) b).say();
}

Compilation and execution :

pi@raspberrypi:/tmp $ g++ c.cc
pi@raspberrypi:/tmp $ ./a.out
From A
From B
From A
pi@raspberrypi:/tmp $

Putting say virtual in A (so implicitely in B) ((A &) b).say(); prints From B because that time there is overriding

Requiring virtual function overrides to use override keyword

Looks like the GCC 5.1 release added exactly the warning I was looking for:

-Wsuggest-override

       Warn about overriding virtual functions that are not marked with the override keyword.

Compiling with -Wsuggest-override -Werror=suggest-override would then enforce that all overrides use override.

What is the 'override' keyword in C++ used for?

The override keyword serves two purposes:

  1. It shows the reader of the code that "this is a virtual method, that is overriding a virtual method of the base class."
  2. The compiler also knows that it's an override, so it can "check" that you are not altering/adding new methods that you think are overrides.

To explain the latter:

class base
{
public:
virtual int foo(float x) = 0;
};


class derived: public base
{
public:
int foo(float x) override { ... } // OK
};

class derived2: public base
{
public:
int foo(int x) override { ... } // ERROR
};

In derived2 the compiler will issue an error for "changing the type". Without override, at most the compiler would give a warning for "you are hiding virtual method by same name".

Why is virtual before declaration and override after?

virtual was introduced right at the beginning of C++ as a keyword. This means you can't use it as a variable name, a class name, a function name, and so on.

override came much later on. In order that its introduction in C++11 didn't break existing code, it doesn't quite attain the status of a keyword; rather it's called an identifier with special meaning. final is similar.

Its curious positioning is specified by the language grammar: an example where allowing it to be at the beginning would be a breaking change is

override :: foo bar()

where override::foo must be a qualified return type of the function bar() rather than an overrider with a explicitly global return type ::foo (Acknowledge @BenVoigt.)

c++ virtual keyword vs overriding function

Consider the following example. The important line to illustrate the need for virtual and override is c->printMe();. Note that the type of c is Base*, however due to polymorphism it is correctly able to call the overridden method from the derived class. The override keyword allows the compiler to enforce that a derived class method matches the signature of a base class's method that is marked virtual. If the override keyword is added to a derived class function, that function does not also need the virtual keyword in the derived class as the virtual is implied.

#include <iostream>

class Base{
public:
virtual void printMe(){
std::cout << "I am the base" << std::endl;
}
};

class Derived: public Base{
public:
void printMe() override {
std::cout << "I am the derived" << std::endl;
}
};

int main() {
Base a;
Derived b;
a.printMe();
b.printMe();
Base* c = &b;
c->printMe();
return 0;
}

The output is

I am the base
I am the derived
I am the derived

Unclear warning on overridden virtual method

Edit to incorporate AnT's comment's:

Clang is behaving correctly by following C++'s name hiding rule. A short and sweet description is available here. In brief...

A member of a derived class hides any member of a base class that has the same name as the derived class member.

This includes base class methods marked virtual.

Original answer follows:

It looks like Clang is giving priority to the function name and not the signature when deciding which method you are trying to call. Here is an example usage of your classes...

int main(void) {
Final f;
f.foo(3.14159);
f.foo(0);

Middle* m = static_cast<Middle*>(&f);
m->foo(3.14159);
m->foo(0);

Base* b = static_cast<Base*>(&f);
b->foo(3.14159);
b->foo(0);
}

Notice the additional warning generated at the call site...

32 : <source>:32:12: warning: implicit conversion from 'double' to 'int' changes value from 3.14159 to 3 [-Wliteral-conversion]
m->foo(3.14159);
~~~ ^~~~~~~

https://godbolt.org/g/qkjqEN

Even though the Middle class inherits the void foo(double) method from Base, Clang seems to be assuming you meant to call the void foo(int) override method declared in Middle.

As others have mentioned, you can add more overrides to help Clang resolve the method you intended to call. Another solution is provided by this StackOverflow question with the using keyword. The declarations in Middle and Final would become the following...

struct Middle : public Decorator<Base>
{
using Base::foo;
void foo(int) override { std::cout << "Middle::foo" << std::endl; };
};

struct Final : public Middle
{
using Base::foo;
void foo(double) override { std::cout << "Final::foo" << std::endl; };
};

https://godbolt.org/g/Qe1WMm



Related Topics



Leave a reply



Submit