【问题标题】:How to properly finalize an object in Fortran?如何正确完成 Fortran 中的对象?
【发布时间】:2016-11-18 12:52:01
【问题描述】:

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

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 对象。但是我怎么能这样做,或者处理释放过程的正确方法是什么?

【问题讨论】:

  • 我添加了end program。该程序按预期工作(仅读取文本文件)。我只想知道我使用call Parser%Deallocate 的方式是否是释放所有数组的正确方式,或者我是否应该使用终结器来实现。另一个问题是何时调用终结器。虽然无法提供一个工作示例,但我对 O-O Fortran 还是很陌生。

标签: fortran finalizer


【解决方案1】:

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

下面清楚地提到什么时候,什么时候不:

如果映像执行因错误(例如分配失败)或因执行 stop-stmt、error-stop-stmt 或 end-program-stmt 而终止,则在终止之前存在的实体不会最终确定.

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

如果Deallocate 是该类型的最终过程,那么该类型的对象的终结与类型绑定过程的调用有一些微妙的区别。在最终确定中,该过程是递归的:组件和父项本身也受最终确定的影响。对于子例程调用,递归必须以某种方式手动出现。

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

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

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

粗略总结一下什么时候完成:

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

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

【讨论】:

  • 感谢您的详细解释。我了解到我应该始终取消分配我分配的所有内容,以免造成内存泄漏。那已经过时了吗?所以不调用deallocate子程序让程序结束就可以了吗?
  • 如果只是内存释放,那么在程序结束时内存泄漏不是问题。它们可能是在以某些方式使用指针时,在哪里完成would indeed help,但同样即使这些不在程序结束时也是如此。可分配对象通常是“安全的”。
  • @THo 它在使用垃圾收集或引用计数的语言中已过时。 Fortran 的可分配变量是一种非常简单的引用计数形式,其中 count 只能是一个。如果您不需要释放内存或将其重新分配给其他东西,则不必显式解除分配可分配变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多