虚拟功能效率和“ final”关键字 [英] Virtual function efficiency and the 'final' keyword

查看:85
本文介绍了虚拟功能效率和“ final”关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一个程序,该程序的类为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆