Con*_*uit 3 c++ performance vtable c++11
考虑一个程序,它有一个类,其中包含如下声明的Foo函数:Foo::fn
virtual void fn();
Run Code Online (Sandbox Code Playgroud)
和一个Foo名为 的子类Bar。将Bar::fn这样声明:
virtual void fn() override final;
Run Code Online (Sandbox Code Playgroud)
导致对fninBar或 的子类的调用Bar更加有效,还是只会阻止 的子类Bar被覆盖fn?如果使用 使调用更加高效final,那么最简单、最有效的定义方法是什么,Bar::fn使其功能与 完全相同Foo::fn?
如果fn定义为finalin ,编译器可以通过指针或静态引用Bar调度调用,因为它知道这是最终的重写器。例如这个程序片段:fnBarBar::fn
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(); }
Run Code Online (Sandbox Code Playgroud)
编译为(有关详细信息,请参阅 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
Run Code Online (Sandbox Code Playgroud)
in 中的调用是通过 vtablewith_foo动态分派的(是间接调用),但 in 中的调用是静态分派到.call *(%rax)with_barBar::fn()
在不改变行为Bar::fn的情况下成为最终重写者的最简单方法是将其定义为静态调用:Foo::fnFoo::fn
struct Bar : Foo {
void fn() final override { Foo::fn(); }
};
Run Code Online (Sandbox Code Playgroud)