2016-11-18 31 views
1

我有一个对象解析文本文件。这是我的主要程序:如何在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 

我读到最后的关键字,并改变了类型定义

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

+0

我加了'end program'。该程序按预期工作(只读取文本文件)。我只是想知道,如果我使用'调用Parser%Deallocate'的方式是释放所有数组的正确方法,或者我应该使用终结器来完成。另外的问题是什么时候确切地敲定了终结者。虽然不能提供一个工作示例,但我对O-O Fortran还是比较陌生的。 – THo

回答

2

在Fortran 2008标准中,最终确定出来的内容在4.5.6.3节中给出。我不会在这里复制所有的时间,但我会总结。

什么明显提到以下从时,是当不是:

如果图像执行被终止,或者通过一个错误(例如,分配失败),或通过停止 - 语句的执行,错误停止-stmt或end-program-stmt,在终止前立即存在的实体尚未最终确定。

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

如果Deallocate是这个类型的最后一个过程,那么这种类型的对象的定型与类型绑定过程的调用有所不同。在最终确定过程中,这个过程是递归的:组件和父母本身都需要完成。使用子程序调用时,递归必须以某种方式手动出现。

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

真正的定稿可以在某些方面强制。如果检查下面的列表,可以想到两个选项:

  • 使Parser对象可以分配并明确地释放它;
  • 将整个事物包装在block结构中。

定稿时发生粗略总结:

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

如果不阅读文档的最终形式你要假装paragraphs 5 and 7 don't exist

+0

感谢您的详细解释。我了解到,我应该总是释放所有我分配的内容而不会造成内存泄漏。那已经过时了吗?因此,不要调用deallocate子例程并让程序结束就好了。 – THo

+1

如果只是内存释放,那么在程序结束时内存泄漏不是问题。它们可能是当指针以某种方式使用时,最终确定[确实会有所帮助](https://stackoverflow.com/q/29038025),但即使这些指针不在程序结束时。 Allocatables通常是“安全的”。 – francescalus

+0

@THO它在使用垃圾收集或引用计数的语言中已经过时。 Fortran的可分配变量是一种非常简单的引用计数形式,其中count只能是一个。如果不需要释放内存或将其重新分配给其他内存,则不必显式释放可分配变量。 –