如何正确完成 Fortran 中的对象?

How to properly finalize an object in Fortran?

我有一个正在解析文本文件的对象。这是我的主要程序:

program main
use Parser_class 
implicit none
type(Parser) :: Parser
call Parser%ProcessFile('data.txt')
call Parser%Deallocate
end program main

类型定义在哪里

module Parser_class
type :: Parser
contains
    procedure, public :: ProcessFile
    procedure, public :: Deallocate
end type Parser
contains
    subroutine ProcessFile(self)
    ...
    end subroutine 
    subroutine Deallocate(self)
    class(Parser) :: self
    ...
    end subroutine 
end module Parser_class

我阅读了 final 关键字并将类型定义更改为

module Parser_class
type :: Parser
contains
    procedure, public :: ProcessFile
    final :: Deallocate
end type Parser
contains
    subroutine ProcessFile(self)
    ...
    end subroutine 
    subroutine Deallocate(self)
    type(Parser) :: self
    ...
    end subroutine 
end module Parser_class

此外,在主程序中我不再有 call Parser%Deallocate。现在任何时候都不会调用终结器。我以某种方式得到这是因为我从不破坏或覆盖 Parser 对象。但是我该怎么做,或者处理释放过程的正确方法是什么?

在 Fortran 2008 标准中,4.5.6.31 部分给出了完成的时间。这里就不一一复制了,总结一下。

后面明确提到的是什么时候,什么时候不是:

If image execution is terminated, either by an error (e.g. an allocation failure) or by execution of a stop-stmt, error-stop-stmt, or end-program-stmt, entities existing immediately prior to termination are not finalized.

这涵盖了您的程序。 Parser 在程序范围内,在程序结束时仍然存在。没有明显的其他事情会导致最终确定。

如果 Deallocate 是该类型的最终过程,则该类型对象的最终化与类型绑定过程的调用存在细微差别。在最终化过程中,这个过程是递归的:组件和父组件本身都要进行最终化。对于子例程调用,递归必须以某种方式手动出现。

在许多情况下,人们并不关心实体是否在程序结束时没有最终确定。毕竟,任何重新分配都是操作系统的问题,而不是程序员的问题。然而,有时确实需要其他形式的整理。

可以通过某些方式强制完成真正的终结。如果检查下面的列表,会想到两个选项:

  • 使 Parser 对象可分配并显式解除分配;
  • 将整个内容包装在一个 block 结构中。

粗略地总结何时完成:

  • 当有释放(指针或可分配)时;
  • 作为带有 intent(out) 个参数的程序启动;
  • 当到达可执行构造或子程序的末尾时,对于未保存的本地对象;
  • 就在对变量进行内部赋值之前;
  • 函数结果的值完成后。

1如果您没有阅读文档的最终形式,您会想假装 paragraphs 5 and 7 don't exist.