As far as I understand, the introduction of override
keyword in C++11 is nothing more than a check to make sure that the function being implemented is the override
ing of a virtual
function in the base class.
Is that it?
As far as I understand, the introduction of override
keyword in C++11 is nothing more than a check to make sure that the function being implemented is the override
ing of a virtual
function in the base class.
Is that it?
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.
override
feature "fixes" this; you have to remember to use it, just as you should have remembered to write the const
;) –
Enervated explicit
class definitions didn't make it into C++11. Huh. –
Consolation explicit
class definition do? Never heard about that at all. –
Sogdian override
when one intends to do it) is more likely than remembering corner cases i.e. there's no generality in copying functions of different prototypes, only irregularities like missing const
or writing char
instead of int
, etc. –
Snakebite override
. Apply it to every function? That'd be nonsense. (And I think non-virtual by default is one of the few things C++ got right.) Apply it to all virtual
functions? That'd also get old really fast in all your base classes. A common style now is to use precisely one of virtual, override and final, whichever is strongest, and I'm not sure there's room for different defaults. Very much unlike with const
. –
Bathos override
, it's not necessarily the case that a better "fix" was missed, I think. –
Bathos override
specifier is mentioned in this answer, which is more futuristic than immediate. The answer suggests that, keep the override
with the virtual
method. In future when one mistakenly changes the signature, its usefulness kicks in. –
Hooghly virtual
in a declaration that also has override
is counter-productive. It's more to write, and more to read. https://mcmap.net/q/110368/-should-i-use-virtual-override-or-both-keywords –
Optative Wikipedia quote:
The override special identifier means that the compiler will check the base class(es) to see if there is a virtual function with this exact signature. And if there is not, the compiler will error out.
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Edit (attempting to improve a bit the answer):
Declaring a method as "override" means that that method is intended to rewrite a (virtual) method on the base class. The overriding method must have same signature (at least for the input parameters) as the method it intends to rewrite.
Why is this necessary? Well, the following two common error cases are prevented:
one mistypes a type in the new method. The compiler, unaware that it is intending to write a previous method, simply adds it to the class as a new method. The problem is that the old method is still there, the new one is added just as an overload. In this case, all calls towards the old method will function just as before, without any change in behavior (which would have been the very purpose of the rewriting).
one forgets to declare the method in the superclass as "virtual", but still attempts to re-write it in a subclass. While this will be apparently accepted, the behavior won't be exactly as intended: the method is not virtual, so access through pointers towards the superclass will end calling the old (superclass') method instead of the new (subclass') method.
Adding "override" clearly disambiguates this: through this, one is telling the compiler that three things are expecting:
If any of these is false, then an error is signaled.
* note: the output parameter is sometimes of different, but related type. Read about covariant and contravariant transformations if interested.
Found "override" is useful when somebody updated base class virtual method signature such as adding an optional parameter but forgot to update derived class method signature. In that case the methods between the base and the derived class are no longer polymorphic relation. Without the override declaration, it is hard to find out this kind of bug.
override
is a great way to discover such problems, good unit test coverage should also help. –
Deejay Yes, this is so. It's a check to make sure one doesn't try an override and mess it up through a botched signature. Here's a Wiki page that explains this in detail and has a short illustrative example:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
C++17 standard draft
After going over all the override
hits on the C++17 N4659 standard draft, the only reference I can find to the override
identifier is:
5 If a virtual function is marked with the virt-specifier override and does not override a member function of a base class, the program is ill-formed. [ Example:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
— end example ]
so I think that possibly blowing up wrong programs is actually the only effect.
To clarify everything about virtual (since I've been running into this repeatedly!).
virtual
is for the base class to tell derived classes a function can be overridden
virtual
in derived classes. If a function has the same name/parameter type list/cv-qual/ref-qual, it will automatically be used correctly.virtual
in derived classes can create subtle bugs, see below)override
is an optional specifier for derived classes to catch errors & document code:
So given:
class base
{
public:
virtual int foo(float x);
};
Here how would fare some different overrides:
// AUTOMATIC virtual function (matches original, no keywords specified)
int foo(float x) { ; }
// Re-specifying "virtual" uselessly (+ see pitfalls below)
virtual int foo(float x) { ; }
// Potential issues: it is unknown if the author intended this to be a
// virtual function or not. Also, if the author DID intend a match but
// made a mistake (e.g. use "int" for the parameter), this will create
// a subtle bug where the wrong function is called with no warning anywhere:
int foo(int x) { ; } // SUBTLE, SILENT BUG! int instead of float param
virtual int foo(int x) { ; } // SUBTLE, SILENT BUG! int instead of float param
// Better approach: use the 'override' identifier to
// make sure the signature matches the original virtual function,
// and documents programmer intent.
int foo(float x) override { ; } // Compiler checks OK + tells coder this is virtual
int foo(int x) override { ; } // COMPILE ERROR, caught subtle bug
virtual int foo(int x) override { ; } // COMPILE ERROR, caught subtle bug
// (and redundant use of "virtual")
Finally (!), the final
specifier can be used instead of override
for the same reasons, but in the case you want no further overrides in derived classes.
© 2022 - 2024 — McMap. All rights reserved.
int override;
as a data member of my class ;-J Wouldn't this "not-a-keyword" conflict with that member then? – Rewordint override(float override) override {...}
. What a mess... :D – Rewordoverride
as a regular identifier cannot conflict with theoverride
specifier, since the latter can only appear in one location, wherein the former can never be syntactically valid. That's precisely why they set it up this way, to enableoverride
andfinal
to have special meanings in the single context where they matter, while not divesting users of the previously available ability to use them as normal identifiers. – Sinuate