I've only been working with C++ for 2~3 months and recently I found out about the identifier, final, that comes after a virtual function. To this day, I believed that omission of virtual will stop the propagation of virtualness but I was wrong. It implicitly propagates.
My question is this. Why allow implicit propagation? Why can't an existence of virtual make a function virtual and absense of virtual make a function not virtual? Is is better in some circumstance? or Was it, back in the day when virtual was first introduced?
According to Clifford's answer, there even is a compiler that generates warning upon absense of virtual.
why is the virtuality of methods implicitly propagated in c
I expected above link to answer my question but it doesn't.
------------ Addition -------------
There are comments about asking the usefulness of this feature. I think final keyword on virtual function is what devirtualizes the function. The function can no longer by overridden, so a derived class must re-declare a function whether it has a same name or not. If final is different from devirtualization, Help me to understand it. If final is not different, then usefulness of devirtualization is self-evident from the fact final was introduced. I agree that forcing explicit virtual will produce bugs, but I'm curious if there are other reasons.
The answer as to why a particular feature exists (or doesn't) is usually rather difficult, as it becomes a matter of guessing and opinions. However, the simple answer could be the principle of least astonishment. Coming up with a scheme that makes sense and works reliably and predictably would be difficult.
What would "devirtualizing" a function even mean? If, at runtime, you're calling a "devirtualized" function on an object, would it use the static type of the pointer instead? If the static type has a virtual function but the runtime type doesn't, what happens?
#include <iostream>
struct A { virtual void f() const { std::cout << "A"; } };
struct B : A { void f() const { std::cout << "B"; } };
struct C : B { virtual void f() const { std::cout << "C"; } };
struct D : C { void f() const { std::cout << "D"; } };
void f(const A& o) { o.f(); }
int main()
{
// "devirtualized" real C++
f(A{}); // "A" "A"
f(B{}); // "A" or "B"? "B"
f(C{}); // "C"? "C"
f(D{}); // oh god "D"
}
There's also the fact that for the vast majority of designs, a virtual function has to stay virtual in the whole hierarchy. Requiring virtual
on all of them would introduce all sorts of bugs that would be very hard to diagnose. C++ usually tries to stay away from features that require discipline to get right.
来源:https://stackoverflow.com/questions/39062002/what-is-the-reason-of-implicit-virtual-ness-propagation