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

如何在Fortran中正确完成对象?,fortran,finalizer,Fortran,Finalizer,我有一个解析文本文件的对象。这是我的主要节目: 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 :: Proc

我有一个解析文本文件的对象。这是我的主要节目:

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

此外,在主程序中,我不再有
调用解析器%Deallocate
。现在任何时候都不会调用终结器。我不知怎的明白了这一点,因为我从未破坏或覆盖
解析器
对象。但是我该怎么做,或者什么是处理解除分配过程的正确方法?

在Fortran 2008标准中,第4.5.6.31节给出了最终确定的时间。我不会在这里一直复制,但我会总结

以下明确提及的是何时、何时不:

如果映像执行因错误(例如分配失败)或执行停止stmt、错误停止stmt或结束程序stmt而终止,则终止前存在的实体不会最终确定

这包括你的计划<代码>解析器在程序的作用域中,它仍然存在于程序的末尾。没有明显的其他事情会导致最终定稿

如果
Deallocate
是该类型的最终过程,则该类型对象的终结与类型绑定过程的调用之间存在微妙的差异。在终结过程中,该过程是递归的:组件和父级本身要进行终结。通过子例程调用,递归必须以某种方式手动出现

在许多情况下,一个人并不关心一个实体在程序结束时是否最终确定。毕竟,任何释放都是操作系统的问题,而不是程序员的问题。然而,有时其他形式的清理确实是可取的

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

  • 使
    解析器
    对象可分配并显式取消分配
  • 将整个内容包装在
    块中
    构造

要粗略总结何时完成,请执行以下操作:

  • 当存在释放时(指针或可分配)
  • 带有
    意图(out)
    参数的as程序启动
  • 当到达可执行构造或子程序的末尾时,对于未保存的本地对象
  • 在变量的内在赋值之前
  • 函数结果的值结束后


1如果您没有阅读文档的最终形式,您将需要假装。

我添加了
结束程序。程序按预期工作(只读取文本文件)。我只是想知道我使用
调用解析器%Deallocate
的方法是否是解除分配所有数组的正确方法,或者我是否应该使用终结器。另外一个问题是何时调用终结器。不过,我不能提供一个有效的示例,我对O-O Fortran还相当陌生。谢谢您的详细解释。我学到了我应该总是释放我分配的所有东西,以免造成内存泄漏。那过时了吗?因此,不调用释放子例程而让程序结束是可以的?如果只是内存释放,那么在程序结束时内存泄漏就不成问题。当指针以某种方式使用时,它们可能会终止,但即使在程序结束时也不会终止。可分配项通常是“安全的”。@但在使用垃圾收集或引用计数的语言中它已过时。Fortran的可分配变量是一种非常简单的引用计数形式,其中计数只能是一个。如果不需要释放内存或再次将其分配给其他对象,则不必显式取消分配可分配变量。