Virtual functions have been in C++ since the very beginning as a means of dynamic polymorphism. However, there was no syntactical mechanism that enforced the compiler to check the correctness of overriding virtual functions in derived classes. With the introduction of C++11, the override keyword became a tool for additional compiler checking.
Without override, the compiler does not guarantee that the function truly overrides the base class method. Signature errors (for example, incorrect type or const) lead to the creation of a new function in the derived class ("shadowing"), which breaks polymorphism and complicates debugging.
Using override when declaring a virtual function in a derived class allows the compiler to check that the signature exactly matches the parent virtual function, and that the function truly overrides the parent one. Otherwise, compilation stops with an error.
Code example:
struct Base { virtual void foo() const {} }; struct Derived : Base { void foo() const override { /* implementation */ } };
If you write void foo() in Derived without const override, the compiler will issue an error.
Key features:
Can a virtual function be left with the 'override' keyword but without the 'virtual' keyword?
Yes, override implies that the function is virtual. Specifying virtual along with override is redundant but not prohibited.
Can there be an error if the function differs only by the const modifier or ref qualifier (for example, & or &&)?
Yes, any differences in the signature, including const/references, break the overriding. For instance, void foo() override does not override void foo() const, and the compiler will catch this thanks to override.
Can 'override' be applied to static functions or constructors?
No. override is only for virtual functions and cannot be applied to static functions, constructors, or destructors (unless they are virtual).
In a large project, a derived class has a typo in the function signature: the function does not actually override, but the developer believes it does, leading to polymorphism not working as expected.
Pros:
Cons:
All derived classes use override, and tests catch errors during the build stage.
Pros:
Cons: