Consider a program that has a class Foo
containing a function Foo::fn
declared like this:
virtual void fn();
and a subclass of Foo
called Bar
. Will declaring Bar::fn
like this:
virtual void fn() override final;
cause calls to fn
in Bar
or subclasses of Bar
to be any more efficient, or will it just keep subclasses of Bar
from overriding fn
? If calls are made more efficient using final
, what is the simplest, most efficient method to define Bar::fn
such that its functionality is exactly that of Foo::fn
?
If fn
is defined as final
in Bar
, the compiler can dispatch calls to fn
through a pointer or reference to Bar
statically since it knows that Bar::fn
is the final overrider. For example, this program fragment:
struct Foo {
virtual void fn();
};
struct Bar : Foo {
void fn() final override;
};
void with_foo(Foo& o) { o.fn(); }
void with_bar(Bar& o) { o.fn(); }
compiles to (See gcc.godbolt.org for details):
with_foo(Foo&):
subq $8, %rsp
movq (%rdi), %rax
call *(%rax)
addq $8, %rsp
ret
with_bar(Bar&):
subq $8, %rsp
call Bar::fn()
addq $8, %rsp
ret
the call in with_foo
is dynamically dispatched (call *(%rax)
is an indirect call) through the vtable, but the call in with_bar
statically dispatches to Bar::fn()
.
The simplest method to make Bar::fn
be the final overrider of Foo::fn
without changing behavior is to define it to statically call Foo::fn
:
struct Bar : Foo {
void fn() final override { Foo::fn(); }
};