Wikipedia 在 C++11 final 修饰符上有以下示例:
struct Base2 {
virtual void f() final;
};
struct Derived2 : Base2 {
void f(); // ill-formed because the virtual function Base2::f has been marked final
};
我不明白引入虚函数并立即将其标记为 final 的意义。这只是一个不好的例子,还是有更多的例子?
原文由 fredoverflow 发布,翻译遵循 CC BY-SA 4.0 许可协议
通常
final
不会用于基类的虚函数定义。final
将由重写函数的派生类使用,以防止进一步的派生类型进一步重写函数。由于覆盖函数通常必须是虚拟的,这意味着任何人都可以在进一步的派生类型中覆盖该函数。final
允许指定一个覆盖另一个但自身不能被覆盖的函数。例如,如果您正在设计一个类层次结构并需要覆盖一个函数,但您不希望类层次结构的用户也这样做,那么您可以在派生类中将函数标记为 final。
由于它在我想添加的评论中被提到了两次:
有些人让基类将非覆盖方法声明为最终方法的一个原因很简单,因为任何试图在派生类中定义该方法的人都会出错,而不是默默地创建一个“隐藏”基类方法的方法。
Base
的开发人员不希望Derived
的开发人员这样做,并希望它产生错误。所以他们写道:使用
Base::foo()
的声明会导致 Derived 的定义产生如下错误:你可以自己决定这个目的是否值得,但我想指出,声明函数
virtual final
并不是防止这种隐藏的完整解决方案。派生类仍然可以隐藏Base::test()
而不会引发所需的编译器错误:Whether
Base::test()
isvirtual final
or not, this definition ofDerived
is valid and the codeDerived o; o.test(); run(&o);
behaves exactly the same.至于对用户的明确声明,我个人认为只是不标记方法
virtual
向用户更清楚地声明该方法不打算被覆盖而不是标记它virtual final
。但我认为哪种方式更清晰取决于开发人员阅读代码以及他们熟悉的约定。