Old*_*ier 9 c++ virtual final c++11
在C++ 11 关键字的各种 解释中final,我看到的是这样的例子.
class base
{
public:
virtual void f() final;
};
class derived : public base
{
public:
virtual void f(); // Illegal due to base::f() declared final.
};
Run Code Online (Sandbox Code Playgroud)
这实际上是一个有用的用途final吗?为什么要在基类中声明一个虚函数(意味着它在派生类中可以有效地重写)然后立即将其标记为final(否定该含义)?有什么用处virtual void f() final?
我可以看到标记derived::f()最终的价值而不是base::f().在这种情况下,base::f()可能有一个很好的基于设计的原因,为什么f()应该是虚拟的,并且derived::f()单独有一个很好的基于设计的原因,为什么没有进一步派生的类应该覆盖它的实现.
如果您不希望多态地覆盖该函数,为什么不放弃虚拟关键字?当然,派生类可能仍会以非多态方式覆盖该函数.virtual void f() final因此,基类中的目的base::f()是以任何方式牢固地不可重写 - 作为虚函数还是非虚函数?如果是这样,那么virtual在这种情况下我们必须添加关键字才能启用它似乎有点不幸final.我认为将非虚拟函数标记为final是合法的.
为什么使用virtual void f() final起源于基类的函数时感觉virtual和感觉final似乎相互矛盾?
How*_*ant 20
将基类函数标记为虚拟和最终是否有任何意义?
是的,至少是暂时的.
我发现自己处于一个相对较大且不熟悉的现有C++源代码库中.大部分代码都是在C++ 11之前编写的.我发现我想确保基类中虚函数的所有覆盖都被标记override.困难的部分是找到所有这些覆盖.
我在基类中标记了虚函数,final编译器很快向我展示了每个覆盖声明的位置.然后很容易装饰我想要的覆盖,并final从基类中删除虚拟.
您可以标记它virtual以表明它在您继承的类中是“虚拟的”(即使您不必这样做),并标记它final以表明从您的类派生的任何类都不能进一步覆盖它。例如,当您实现抽象基类时,可能会发生这种情况。这是C++11,所以没有用;override是一个更好的指示,因为它是由编译器强制执行的。
另一种可能性:您希望这个方法不被覆盖,但您希望能够在不重新编译的情况下更改它。请记住,这virtual意味着它位于虚拟表中。即使编译器不会让你覆盖它。
我认为你所展示的例子的目的是展示virtual和最终之间的优先级,仅此而已。这是 的最小用途final,而不是有用的用途。
将非虚拟方法标记为final没有意义,因为无论如何您都无法覆盖它们。如果您希望编译器防止隐藏,那是一个完全不同的问题,与方法无关final。从某种意义上说,非虚拟方法已经是最终的,但可以隐藏。