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
- There is no need to use
virtual
in derived classes. If a function has the same name/parameter type list/cv-qual/ref-qual, it will automatically be used correctly.
- (actually, using
virtual
in derived classes can create subtle bugs, see below)
override
is an optional specifier for derived classes to catch errors & document code:
- Tells the compiler: "make sure there is an EXACT virtual function I am overriding"
- Avoids creating a DIFFERENT function signature by mistake that would cause a subtle bug (i.e. 2 slightly different functions that are meant to be the same)
- Tells coders this is overriding a virtual function
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.