是否应该标记具有公共非虚拟析构函数的类" final"?

时间:2015-08-04 13:30:43

标签: c++ c++11

要关闭选民,请帮助我改进问题,以便重新开启:How can I improve this question so that it gets reopened?

Herb Sutter wrote

  

基类析构函数应该是public和virtual,或者   受保护和非虚拟。

根据该指南,如果您有一个具有公共非虚拟析构函数的类,那么该类不应该用作基类。 为什么不标记它final来强制执行?

但Sutter还wrote以下内容,暗示final不需要使用:

  

Re" final的使用更为罕见" - 好吧,他们有点儿。我不知道   很多,并且在标准化期间Bjarne一再要求   它解决的问题的例子和应该使用的模式,   而且我不记得任何突出的主要因素。

另一个相关的引用,暗示final现在应该可以使用,来自Scott Meyer的Effective C ++,第7项:

  

如果您曾试图从标准容器或任何容器继承   其他类带有非虚拟析构函数,抵制诱惑!   (不幸的是,C ++没有提供类似于派生的预防机制   Java的最终课程或C#的密封课程。)

另一个数据点是standard library has no types marked "final",但其原因似乎是避免破坏代码。

这里有类似的问题,但并不完全重复,因为它错过了受保护的,非虚拟的"选项:Default to making classes either `final` or give them a virtual destructor?

2 个答案:

答案 0 :(得分:6)

  

根据该指南,如果您有一个具有公共非虚拟析构函数的类,则该类不应该用作基类。为什么不将它标记为最终执行?

因为它是指南适合某些情况,但不是全部,所以为什么你“强制”它呢?

通过virtual函数调用的动态多态性尚未配置,但这是非常好和不允许的继承,但这不是我们使用继承的唯一场景。

C ++是多范式的,开始实施仅适合用例子集的窄方法没有意义。从我所知道的,你的建议基本上归结为禁止人们使用继承,除非他们也将使用动态多态。

答案 1 :(得分:3)

我经常将类声明为final,除非它们是

  • 打算用作基类或
  • POD类型。

我认为明确设计继承是一件好事(毕竟应该谨慎使用)。如果我不打算将类设计为基类,我会通过声明它final来记录它。如果稍后我发现从该类派生是有用的,那么必须去除final是一个很好的机会来检查是否满足使其成为可行基类的其他条件。

我通常不会将POD类型声明为final,因为我没有看到这样做有任何好处,并且从它们派生有时对于利用空基础优化很有用。