I've been having a discussion with my coworkers as to whether to prefix overridden methods with the virtual keyword, or only at the originating base class.
I tend to prefix all virtual methods (that is, methods involving a vtable lookup) with the virtual keyword. My rationale is threefold:
Given that C++ lacks an override keyword, the presence of the virtual keyword at least notifies you that the method involves a lookup and could theoretically be overridden by further specializations, or could be called through a pointer to a higher base class.
Consistently using this style means that, when you see a method (at least within our code) without the virtual keyword, you can initially assume that it is neither derived from a base nor specialized in subclass.
If, through some error, the virtual were removed from IFoo, all children will still function (CFooSpecialization::DoBar would still override CFooBase::DoBar, rather than simply hiding it).
The argument against the practice, as I understood it, was, "But that method isn't virtual" (which I believe is invalid, and borne from a misunderstanding of virtuality), and "When I see the virtual keyword, I expect that means someone is deriving from it, and go searching for them."
The hypothetical classes may be spread across several files, and there are several specializations.
class IFoo {
public:
virtual void DoBar() = 0;
void DoBaz();
};
class CFooBase : public IFoo {
public:
virtual void DoBar(); // Default implementation
void DoZap();
};
class CFooSpecialization : public CFooBase {
public:
virtual void DoBar(); // Specialized implementation
};
Stylistically, would you remove the virtual keyword from the two derived classes? If so, why? What are Stack Overflow's thoughts here?
I would tend not to use any syntax that the compiler will allow me to omit. Having said that, part of the design of C# (in an attempt to improve over C++) was to require overrides of virtual methods to be labeled as "override", and that seems to be a reasonable idea. My concern is that, since it's completely optional, it's only a matter of time before someone omits it, and by then you'll have gotten into the habit of expecting overrides to be have "virtual" specified. Maybe it's best to just live within the limitations of the language, then.
A function once a virtual always a virtual.
So in any event if the virtual keyword is not used in the subsequent classes, it does not prevent the function/method from being 'virtual' i.e. be overridden. So one of the projects that I worked-in, had the following guideline which I somewhat liked :
/*virtual*/ void guiFocusEvent();
C++11, use the 'final' keyword along with the 'override' Ex:void guiFocusEvent() override final;
I can think of one disadvantage: When a class member function is not overridden and you declare it virtual, you add an uneccessary entry in the virtual table for that class definition.
Adding
virtual
does not have a significant impact either way. I tend to prefer it but it's really a subjective issue. However, if you make sure to use theoverride
andsealed
keywords in Visual C++, you'll gain a significant improvement in ability to catch errors at compile time.I include the following lines in my PCH:
Note: My answer regards C++03 which some of us are still stuck with. C++11 has the
override
andfinal
keywords as @JustinTime suggests in the comments which should probably be used instead of the following suggestion.There are plenty of answers already and two contrary opinions that stand out the most. I want to combine what @280Z28 mentioned in his answer with @StevenSudit's opinion and @Abhay's style guidelines.
I disagree with @280Z28 and wouldn't use Microsoft's language extensions unless you are certain that you will only ever use that code on Windows.
But I do like the keywords. So why not just use a #define-d keyword addition for clarity?
or
The difference being your decision on what you want to happen in the case you outline in your 3rd point.
Though I would argue that it is a programming error so there is no "fix" and you probably shouldn't even bother mitigating it but should ensure it crashes or notifies the programmer in some other way (though I can't think of one right now).
Should you chose the first option and don't like adding
#define
's then you can just use comments like:And that should do the job for all cases where you want clarity, because I don't consider the word virtual to be clear enough for what you want it to do.
I completely agree with your rationale. It's a good reminder that the method will have dynamic dispatch semantics when called. The "that method isn't virtual" argument that you co-worker is using is completely bogus. He's mixed up the concepts of virtual and pure-virtual.