虚拟功能效率和“ final”关键字 [英] Virtual function efficiency and the 'final' keyword
问题描述
考虑一个程序,该程序的类为 Foo
,其中包含一个声明为以下内容的函数 Foo :: fn
:
Consider a program that has a class Foo
containing a function Foo::fn
declared like this:
virtual void fn();
以及 Foo
的子类,称为 Bar
。将这样声明 Bar :: fn
and a subclass of Foo
called Bar
. Will declaring Bar::fn
like this:
virtual void fn() override final;
导致在<$ c中调用 fn
$ c> Bar 或 Bar
的子类来提高效率,还是只保留 Bar的子类
是否覆盖了 fn
?如果使用 final
使调用更加有效,那么定义 Bar :: fn
这样的最简单,最有效的方法是什么?它的功能完全是 Foo :: fn
的功能?
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
?
推荐答案
如果在 Bar
中将 fn
定义为 final
,则编译器可以通过指针或对 Bar
的引用静态地将指针分派给 fn
的调用,因为它知道 Bar :: 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(); }
编译为(有关详细信息,请参见gcc.godbolt.org ):
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
with_foo
中的呼叫是动态调度的( call *( %rax)
是通过vtable的间接调用),但是 with_bar
中的调用静态分配给 Bar :: fn ()
。
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()
.
使 Bar :: fn
为最终值的最简单方法 Foo :: fn
的替代者,无需更改其行为,就是将其定义为静态调用 Foo :: 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(); }
};
这篇关于虚拟功能效率和“ final”关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!