我正在阅读一篇很棒的awesome C++11 tutorial,作者在解释final
关键字时提供了这个示例:
struct B {
virtual void f() const final; // do not override
virtual void g();
};
struct D : B {
void f() const; // error: D::f attempts to override final B::f
void g(); // OK
};
因此使用final
关键字有意义吗?在我看来,您可以避免在此处使用virtual
关键字,并阻止覆盖f()
。
答案 0 :(得分:32)
如果不将函数标记为virtual
和final
,那么子类仍然可以实现该函数并隐藏基类函数。
通过使函数virtual
和final
,子类无法覆盖或隐藏函数。
答案 1 :(得分:11)
是的!在您提供的示例中,final
关键字可以阻止任何派生类覆盖f()
,正如您所说的那样。如果该函数是非虚拟的,则允许D:f()
隐藏函数的基类版本:
struct B {
void f() const; // do not override
virtual void g();
};
struct D : B {
void f() const; // OK!
void g(); // OK
};
通过使f()
成为virtual
和final
函数,任何覆盖或隐藏的尝试都会导致编译错误。
答案 2 :(得分:2)
你的直觉是正确的:制作一个函数virtual
只是立即用final
限制它对非虚函数没有任何好处。这只是一个简短的示例代码片段来演示该功能。
此外,正如其他答案中所述,这实际上打破了隐藏功能 - 您无法在f
或任何一个中使用相同参数列表的D
函数它的派生类
当您决定在模型中限制f
时,这是一项权衡。由于无法在此处执行实际的虚拟调用,因此您基本上处于劣势且没有任何好处。