Как правильно завершить объект в Фортране?

У меня есть объект, разбирающий текстовый файл. Вот моя основная программа:

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 объект. Но как я могу это сделать, или как правильно обработать процесс освобождения?

1 ответ

Решение

В стандарте Fortran 2008 время завершения дается в разделе 4.5.6.31. Я не буду копировать все время здесь, но я подведу итоги.

Что четко указано, когда, когда нет:

Если выполнение образа завершается либо из-за ошибки (например, ошибки выделения), либо из-за выполнения stop-stmt, error-stop-stmt или end-program-stmt, сущности, существующие непосредственно перед завершением, не завершаются.

Это охватывает вашу программу. Parser находится в области действия программы, и она все еще существует в конце программы. Нет очевидных других вещей, которые могли бы привести к завершению.

Если Deallocate является окончательной процедурой для типа, тогда есть тонкие способы, которыми финализация объекта этого типа отличается от вызова связанной с типом процедуры. В финализации процесс рекурсивный: компоненты и родители сами подлежат финализации. При вызове подпрограммы эта рекурсия должна каким-то образом появляться вручную.

Во многих случаях все равно, что сущность не завершена в конце программы. В конце концов, любое освобождение - это проблема операционной системы, а не программиста. Однако бывают случаи, когда другие формы уборки действительно желательны.

Истинная финализация может быть вызвана несколькими способами. Если рассмотрен список ниже, на ум приходят два варианта:

  • сделать Parser объект размещается и явно освобождается от него;
  • обернуть все это в block построить.

Чтобы грубо суммировать, когда происходит завершение:

  • когда есть освобождение (указатель или выделение);
  • как процедура запуска с intent(out) аргументы;
  • при достижении конца исполняемой конструкции или подпрограммы для несохраненных локальных объектов;
  • непосредственно перед присваиванием переменной;
  • после того, как значение результата функции закончено с.

1 Если вы не читаете окончательную форму документа, вы можете сделать вид, что параграфы 5 и 7 не существуют.

Другие вопросы по тегам