【问题标题】:Fortran FINAL procedure for ABSTRACT typeABSTRACT 类型的 Fortran FINAL 过程
【发布时间】:2018-06-14 17:04:55
【问题描述】:

我可以将final 过程添加到抽象类型吗?

假设最终过程如下所示:

subroutine finalize(this)
   type(bin_tree_t), intent(inout) :: this

   deallocate(this%head)
end subroutine finalize

我的编译器 (ifort 18.0.1) 给出“错误 #8313:TYPE(derived-type-spec) 不应指定抽象类型”。我明白了,但最终子例程的虚拟参数不能是多态的。

如果这不可能,那么这可能是标准委员会的有意选择,还是只是疏忽?

【问题讨论】:

  • 您自己回答了技术原因。你应该向委员会的人询问原因的原因,也许史蒂文莱昂内尔可以告诉我们一些事情,他有时会来这里。
  • 我认为您也不认为这是可能的。这让我很惊讶,所以我想我可能会遗漏一些东西。也许只是没有很多用例。
  • 是的。但我也可能错过了一些东西。在 gfortran 开始完全支持它们之前,我不会开始使用 FINAL 过程。

标签: fortran abstract-class destructor


【解决方案1】:

抽象类型不可能有最终子例程。正如您所注意到的,此类子例程的参数不能是多态的,我们不能用type(spec) 实例化抽象类型。

当一个对象被终结时,最终选择的子例程是一个参数类型为要终结对象的动态类型的子例程。任何对象都不能有动态类型和抽象类型。最终子例程不会被继承(并且可能不会被覆盖)。

我可以想象抽象类型的最终子例程会很好的用例。事实上,我们希望抽象类型执行的任何终结都应该由扩展类型完成。请注意,抽象父级的可终结组件仍将被终结。

我无法评论标准委员会的想法,但这些案例似乎没有比我们现在拥有的简单的最终确定规范更有价值。


我说过最终子程序的参数不能是多态的。这是 Fortran 2008 标准的 C480。问“允许多态参数会导致什么问题?”是一个完全合理的问题。

我们所拥有的终结过程并没有根据通用解析、覆盖或继承来表达为实体选择的最终子例程。选择是“如果有适合动态类型的子例程,就接受它”。相反,如果允许多态参数:“如果有适合动态类型的子例程,则采用它;如果没有,则遍历父类型......”。后一个概念在其他地方很少出现。

请注意,一旦扩展类型完成,父类型就完成了(即使该扩展类型没有对应的最终子例程)。

总之,在我看来,并没有积极的愿望来禁止抽象类型的 final 子例程,但允许它们的成本太高了。当前方法的定义非常简单。定稿可以用不同的方式编写吗?是的。唉,我们需要有更详细知识的人来详细说明为什么选择这种特殊方式。

【讨论】:

  • 很好的背景信息,但这无法解释为什么最终子例程的传递虚拟参数不能是多态的(即class(spec), intent(XX) :: this)。如果标准允许这样做会导致什么问题?
  • 有点啰嗦,但我希望它能适当扩展。如果您认为有什么不清楚的地方,请告诉我。 (我稍后也会重新起草。)
  • 您至少在某些方面做出了重大贡献。首先,你帮助我更清楚地提出了这个问题(见我上面的评论)。其次,您(和 Vladimir F)已经证实了我的怀疑,即即使对专家来说答案也不明显。
猜你喜欢
  • 2021-11-03
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多