我正在使用类型定义中的final
关键字在Fortran中编写对象析构函数。但是当这些实例的数组离开范围时,不会调用析构函数。
module problem_module
type :: destructable_object
integer :: nr
contains
final :: destruct
end type destructable_object
type :: collection
type(destructable_object) :: single_member
type(destructable_object), dimension(3) :: multiple_members
end type collection
contains
subroutine destruct(instance)
type(destructable_object), intent(in) :: instance
write(*,*) "Destruct ",instance%nr
end subroutine destruct
end module problem_module
在此示例模块中,destructable_object
类型的任何标量都将使用final
关键字引发的破坏例程进行解构。但是,destructable_object
类型的数组不会被解构。对于其他类中的destructable
个对象,如果它们是标量,也只能被正确地解构(在这个例子中,single_member被正确地解构,而multi_members则没有)。这与包含对象是否在数组中无关。所以,例如
program main
! Destructors are only called at end of subroutines, not at the end of the program.
! Therefore, I move the entire program to a subroutine.
call main_execute
contains
subroutine main_execute
use problem_module
implicit none
type(destructable_object) :: single_instance
type(destructable_object), dimension(3) :: multiple_instances
type(collection) :: single_collection
type(collection), dimension(3) :: multiple_collections
single_instance%nr = 1
multiple_instances(1)%nr = 2
multiple_instances(2)%nr = 3
multiple_instances(3)%nr = 4
single_collection%single_member%nr = 5
single_collection%multiple_members(1)%nr = 6
single_collection%multiple_members(2)%nr = 7
single_collection%multiple_members(3)%nr = 8
multiple_collections(1)%single_member%nr = 9
multiple_collections(1)%multiple_members(1)%nr = 10
multiple_collections(1)%multiple_members(2)%nr = 11
multiple_collections(1)%multiple_members(3)%nr = 12
multiple_collections(2)%single_member%nr = 13
multiple_collections(2)%multiple_members(1)%nr = 14
multiple_collections(2)%multiple_members(2)%nr = 15
multiple_collections(2)%multiple_members(3)%nr = 16
multiple_collections(3)%single_member%nr = 17
multiple_collections(3)%multiple_members(1)%nr = 18
multiple_collections(3)%multiple_members(2)%nr = 19
multiple_collections(3)%multiple_members(3)%nr = 20
end subroutine main_execute
end program main
返回
Destruct 1
Destruct 5
Destruct 9
Destruct 13
Destruct 17
destructable
对象的所有标量实例,而不是destructable
对象的数组,与其情况无关。如果我想要一个带析构函数的对象数组,我可以通过在容器对象中添加一个间接层来解决这个问题。这看起来很笨拙,需要嵌套的%-constructions或一堆指针。是否有更优雅的方法来强制销毁数组?
答案 0 :(得分:4)
必须为标量和要完成的类型数组的每个等级指定不同的最终子例程。 E.g:
module problem_module
type :: destructable_object
integer :: nr
contains
final :: destruct, destruct_array
end type destructable_object
type :: collection
type(destructable_object) :: single_member
type(destructable_object), dimension(3) :: multiple_members
end type collection
contains
subroutine destruct(instance)
type(destructable_object), intent(in) :: instance
write(*,*) "Destruct ",instance%nr
end subroutine destruct
subroutine destruct_array(instance)
type(destructable_object), intent(in) :: instance(:)
write(*,*) "Destruct array ",instance%nr
end subroutine destruct_array
end module problem_module
为避免多重定义,您可以将元素属性添加到子例程中:
module problem_module
type :: destructable_object
integer :: nr
contains
final :: destruct
end type destructable_object
type :: collection
type(destructable_object) :: single_member
type(destructable_object), dimension(3) :: multiple_members
end type collection
contains
impure elemental subroutine destruct(instance)
type(destructable_object), intent(in) :: instance
write(*,*) "Destruct ",instance%nr
end subroutine destruct
end module problem_module
(我还添加了 impure 以便在元素过程中使用写入)。
我强烈建议使用更新的编译器。旧编译器可能无法完全实现 final 内容。