Ani*_*kar 13 c++ virtual final c++11
C++ 11添加了最终版.
最后!
我明白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.
}
};
Run Code Online (Sandbox Code Playgroud)
从上面,我相信Baz是final的,我应该不是需要指定它的virtual成员函数bar也是final.由于Baz不能继承,覆盖的问题bar超出了范围.不过我的编译VC++ 2015,对此非常安静.目前我还没有对其他任何人进行测试.
如果有人能够对这个话题有所了解,我会很高兴.标准的引用(如果有的话)将非常感激.还请说明我不知道的任何角落案件,这可能导致我的逻辑信念失败.
所以,我的问题是:是否 final class 隐含地暗示其 virtual 功能 final 也是如此?应该是?请澄清.
我之所以这么说是因为final功能符合去虚拟化的要求,这是一个很好的优化.任何帮助表示赞赏.
Nic*_*las 13
我之所以这么说是因为最终功能符合去虚拟化的要求,这是一个很好的优化.
他们呢?"去虚拟化"不是C++标准的一部分.或者至少,不是真的.
去虚拟化仅仅是"似乎"规则的结果,该规则指出实现可以做任何它喜欢的事情,只要实现行为"好像"它正在做标准所说的.
如果编译器可以在编译时检测到通过多态类型对虚拟成员函数的特定调用将无可否认地调用该函数的特定版本,则允许它避免使用虚拟调度逻辑并静态调用该函数.这表现为"好像"它使用了虚拟调度逻辑,因为编译器可以证明这是已经被调用的函数.
因此,该标准没有定义何时允许/禁止去虚拟化.编译器在内联一个带有指向虚拟类型的指针的类时,可能会发现正在传递的指针指向一个在其内联函数中声明的本地堆栈变量.或者编译器可以将特定的内联/调用图跟踪到特定多态指针/引用的原点.在这些情况下,编译器可以将调用去虚拟化为该类型.但只有这样才能足够聪明.
编译器是否会将所有虚函数调用虚拟化为final类,无论这些方法是否final自己声明?有可能.它可能不会.它甚至可能不会final对在多态类型上声明的方法的任何调用进行虚拟化.这是一个有效的(如果不是特别明亮的)实现.
您要问的问题是具体实施.它可能因编译器而异.
但是,final正如您所指出的,正在声明的类应该是编译器的足够信息,以便对指向final类类型的指针/引用的所有调用进行虚拟化.如果编译器没有这样做,那么这是一个实施质量问题,而不是标准问题.
要从此处[class.virtual / 4]引用C ++标准草案:
如果
f某个类中的虚函数B用virt-specifier 标记,而从该函数派生final的类中的虚函数覆盖,则程序格式错误。DBD::fB::f
在这里[class / 3]:
如果一个类用class-virt-specifier 标记,
final并且在基本子句中显示为基本类型的说明符(Clause [class.derived]),则程序格式错误。
因此,回答问题;
是否
finalclass暗含暗示其virtual功能final也是如此?应该是?请澄清。
因此,至少不是正式的。在这两种情况下,任何违反任何一条规则的尝试都将得到相同的结果。程序格式错误,无法编译。A final class意味着该类不能从其派生,因此,其结果virtual不能被覆盖。
应该是?至少在形式上,也许不是;它们是相关的,但不是同一回事。也无需正式要求一个暗示另一个,效果自然而然。任何违规都会导致相同的结果,即编译失败(希望通过适当的错误消息来区分两者)。
激发查询和虚拟呼叫的虚拟化动机。这并不总是立即受final类或方法的影响(尽管它们提供了帮助),但虚函数和类层次结构的常规规则适用。
如果编译器可以确定在运行时将始终调用特定方法(例如,使用自动对象,即“在堆栈上”),则无论该方法是否为最终方法,编译器仍然可以应用这种优化。这些优化属于“按条件”规则,该规则允许编译器应用任何转换,只要可观察到的行为与“已执行原始代码”为准即可。
| 归档时间: |
|
| 查看次数: |
2499 次 |
| 最近记录: |