What is the difference in between declaring a new (non override) member function virtual final
versus just non-virtual?
I'm guessing a virtual final
member function (that does not override anything) will be optimized to non-virtual by the compiler anyways, but maybe I'm wrong here.
Having a virtual method means you are a legal target for dynamic casting, and you cannot be standard layout.
ABI wise I suspect compilers aren't going to do extra work to eliminate final
methods, so the vtable with the entry will still exist unless the entire class is eliminated under "as-if".
But at every point of call, they can bypass the vtable and call the method directly (presuming the address of the method is known at the call site by the compiler; it is plausible some dynamic loading settings could make the vtable known at the call site, but the method address not).
This also prevents derived classes from overriding this exact signature. Ie:
struct Parent {
void foo();
};
struct Child:Parent {
void foo();
};
this is legal, while
struct Parent {
virtual void foo() final;
};
struct Child:Parent {
void foo();
};
is not. Relying on this is fragile, as
struct Parent {
virtual void foo() final;
};
struct Child:Parent {
void foo() const;
};
is again legal.