gpt4 book ai didi

c++ - C++ final 是否在所有方面都暗示 final?

转载 作者:IT老高 更新时间:2023-10-28 23:14:01 26 4
gpt4 key购买 nike

C++11 added final.

终于!

我了解 final 做了两件事:

  • 使类不可继承。
  • 使类中的(虚拟)函数不可覆盖(在派生类中)。

这两者似乎是相互独立的。但以以下为例:

class Foo
{
public:
virtual void bar()
{
//do something unimportant.
}
};
class Baz final : public Foo
{
public:
void bar() /*final*/ override
{
//do something more important than Foo's bar.
}
};

从上面,我相信Bazfinal,我应该需要指定它的virtual成员函数bar也是final。由于 Baz 不能被继承,覆盖 bar 的问题超出了范围。但是我的编译器 VC++ 2015 对此非常安静。目前我还没有在其他任何人身上测试过。

如果有人能对这个话题有所了解,我会很高兴。来自标准的报价(如果有的话)将不胜感激。另外请说明我不知道的任何极端情况,这可能会导致我的逻辑信念失败。

所以,我的问题是:一个 final class 是否隐含了它的 virtual 函数是 final 吗?应该是?请澄清。


我问这个的原因是因为 final 函数符合 de-virtualization 的条件,这是一个很好的优化。任何帮助表示赞赏。

最佳答案

The reason I am asking this is because final functions become qualified for de-virtualization, which is a great optimization.

有吗? “去虚拟化”不是 C++ 标准的一部分。或者至少,不是。

去虚拟化只是“好像”规则的结果,该规则规定实现可以做任何它喜欢的事情,只要实现表现得“好像”它正在按照标准所说的那样行事。

如果编译器可以在编译时检测到通过多态类型对虚拟成员函数的特定调用将无可否认地调用该函数的特定版本,则允许避免使用虚拟调度逻辑和调用静态函数。这表现得“好像”它使用了虚拟调度逻辑,因为编译器可以证明这是本应调用的函数。

因此,该标准没有定义何时允许/禁止去虚拟化。编译器在内联一个接受基类类型指针的函数时,可能会发现被传递的指针指向在它被内联的函数中声明的本地堆栈变量。或者编译器可以将特定的内联/调用图追踪到特定多态指针/引用的起点。在这些情况下,编译器可以将调用去虚拟化为该类型。但前提是它足够聪明。

编译器是否会将所有对 final 类的虚函数调用去虚拟化,而不管这些方法本身是否声明为 final?它可能。它可能不会。它甚至可能不会对在多态类型上声明的 final 方法的任何调用进行去虚拟化。这是一个有效的(如果不是特别聪明的话)实现。

您要问的问题是特定于实现的。它可能因编译器而异。

但是,正如您所指出的,声明为 final 的类应该足以让编译器将所有对 final 类的指针/引用的调用虚拟化类型。如果编译器不这样做,那就是实现质量问题,而不是标准问题。

关于c++ - C++ final 是否在所有方面都暗示 final?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36895012/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com