我是使用 Fortran 的 OOP 的初学者,我正在尝试编写一个程序,其中包含处理多态变量作为参数的过程。尽管我的原始代码要复杂得多(许多过程、几个派生类型等),但我可以隔离一个简单的问题示例,例如:我有一个复制多态变量并稍微修改此副本的过程。
我能够使用子程序成功编写我的测试程序:
MODULE my_module
type :: my_type
real :: data
endtype my_type
type, extends(my_type) :: my_derived_type
end type my_derived_type
CONTAINS
subroutine sub_copy(old,new)
implicit none
class(my_type), intent(in) :: old
class(my_type), allocatable, intent(out) :: new
allocate(new, source = old)
new%data = new%data + 1
end subroutine sub_copy
END MODULE my_module
PROGRAM my_prog
use my_module
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y
x%data = 1.0
call sub_copy(x,y)
print*,y%data
deallocate(y)
END PROGRAM my_prog
这在预期结果和内存分配/释放方面都表现良好。
但是,我一直在努力尝试制作一个可以完成相同工作的 Fortran函数。
似乎以与子例程类似的方式定义的函数(见下文)不能简单地用作
y = fun_copy(x)
我的 gfortran 编译器(v5.0.0)抱怨:
Error: Assignment to an allocatable polymorphic variable at (1) is not yet supported
我在这里和那里读到过,我的编译器确实不支持这样的分配。等待这一点,我试图通过定义我自己的赋值运算符 (=) 来解决这个问题。以下代码有效:
MODULE my_module
type :: my_type
real :: data
endtype my_type
type, extends(my_type) :: my_derived_type
end type my_derived_type
interface assignment(=)
module procedure myassign
end interface
CONTAINS
function fun_copy(old) result(new)
implicit none
class(my_type), intent(in) :: old
class(my_type), allocatable :: new
allocate(new, source = old)
new%data = new%data + 1
end function fun_copy
subroutine myassign(new,old)
class(my_type), intent(in) :: old
class(my_type), allocatable, intent(out) :: new
allocate(new, source=old)
end subroutine
END MODULE my_module
PROGRAM my_prog
use my_module
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y
x%data = 1.0
y = fun_copy(x)
print*,y%data
deallocate(y)
END PROGRAM my_prog
从某种意义上说,它确实可以将 的副本x
创建为y
. 然而,检查这个简单的测试程序的内存预算(我在 OS X 上使用Instrument软件),似乎有些内存在它结束之前没有被释放。我怀疑复制函数和赋值子例程都分配了内存,并且我只释放了一次,留下了一个分配。
由于我打算在更复杂的代码中大量使用这样的例程,我真的很关心内存分配/释放。当然,我可以使用程序的子程序版本,但如果有办法,我更喜欢函数版本。
有没有办法处理这样的问题?