Virtual function efficiency and the 'final' keyword

前端 未结 2 1990
灰色年华
灰色年华 2021-01-15 18:29

Consider a program that has a class Foo containing a function Foo::fn declared like this:

virtual void fn();

and

2条回答
  •  野的像风
    2021-01-15 19:16

    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(); }
    };
    

提交回复
热议问题