C++11 Annoyance Avoiders
I’ve always been torn as to whether or not to annotate derived class member functions intended to override base class members as virtual. Even though it’s unnecessary to do so, I have always preferred to declare them as virtual because it’s just another little reminder to me (besides the colon followed by the base class name at the top of the class definition) that the class I’m coding up is indeed a derived one.
With the introduction of the context-sensitive “override” keyword into C++11, I’ve decided that I’m still going to annotate overriding derived class member functions as a reminder of a class’s derived-ness. However, instead of adorning them with virtual, I’m going to use override instead. Even though they serve basically the same purpose, the compiler uses override to preclude inadvertent hiding of base class member functions that are intended to be overridden.
Assume that the writer of the Derived class below intended to override Base::hiddenFunc(double) but mistakenly wrote Derived::hiddenFunc(int32_t) instead. As you can see from the console output below the code graphic, a loss of precision occurs whenever a user of Derived calls hiddenFunc with a double.
By using override instead of virtual, the potential “gotcha” is avoided. Because the use of override explicity tells the compiler of the programmer’s intention to override, and not hide, Base::hiddenFunc, the code below doesn’t even compile.
C++11 and C++14 provide lots of little, conscientious, “annoyance avoiders” like override (auto, brace initialization, nullptr, lambdas, std::array, smart pointers, etc). Thanks to the benevolent stewardship of Stroustrup/Sutter and the rest of the ISO WG21 C++ committee membership, these little gems make programming in the language more intrinsically rewarding and safer than it is now. If you’re not a hard core anti-C++ zealot, then maybe now is the time time to give the language a try.