Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
342 views
in Technique[技术] by (71.8m points)

c++ - Virtual function efficiency and the 'final' keyword

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...