被标记为'virtual final'的基类方法会带来额外的开销吗?

问题描述 投票:1回答:2

假设我想使用两个方法创建一个类Basefoo(int)bar(int)。我希望以以下方式定义它们:

  • Base::foo必须在派生的非抽象类中重写
  • Base::bar不能在派生类中重写

第一个目标可以通过将foo标记为virtual int foo(int) = 0使其抽象来实现。通过将bar标记为virtual int bar(int) final以使其最终化,可以满足第二个要求。这是结果代码:

class Base
{
public:
    virtual int foo(int n) = 0;
    virtual int bar(int n) final
    {
        return n + 42;
    }
};

以及从Base派生的示例类:

class Derived : Base
{
public:
    virtual int foo(int n) override
    {
        return n * n;
    }
    int bar(int n) // compilation error here
    {
        return n + 43;
    }
};

正如我们想要的那样,尝试覆盖Base::bar已触发编译错误。

现在,我的问题是:将函数标记为virtual final是否会引起开销,因为即使函数不能被重写,但函数仍为virtual(动态分配)?

编辑

不要介意缺少虚拟析构函数~Base(),此处不是要缩短代码的地方。

c++ inheritance methods overriding virtual-functions
2个回答
1
投票

编译器可能会取消虚拟化此调用:

struct Base {
    virtual int bar(int n) final {
        return n + 42;
    }
};

struct Derived : Base { };

int foo(Derived& d, int n) {
    return d.bar(n);
}

[becomes-O1

foo(Derived&, int):
        lea     eax, [rsi+42]
        ret

如果没有final,我们将得到一个间接调用:

foo(Derived&, int):
        sub     rsp, 8
        mov     rax, QWORD PTR [rdi]
        call    [QWORD PTR [rax]]
        add     rsp, 8
        ret

0
投票

在您的情况下,没有开销,因为您的类不会从任何类继承来定义您的最终函数,因此,无论虚拟声明如何,编译器都会生成对其地址的直接调用。

© www.soinside.com 2019 - 2024. All rights reserved.