Fortran多态,函数和分配 [英] Fortran polymorphism, functions and allocation
问题描述
我是Fortran的OOP的初学者,我正在尝试编写一个程序来处理多态变量作为参数。
虽然我的原始代码要复杂得多(很多过程,几个派生类型等),但我可以隔离一个我的问题的简单例子,例如:我有一个过程复制一个多态变量并略微修改此副本。 / p>
我能够使用子程序成功编写我的测试程序:
MODULE my_module
type :: my_type
real :: data
endtype my_type
type,extends(my_type) :: my_derived_type
结束类型my_derived_type
CONTAINS
子程序sub_copy(旧的,新的)
隐式无
class(my_type),intent (in):: old
class(my_type),allocatable,intent(out):: new
allocate(new,source = old)
new%data = new%data + 1
end子程序sub_copy
END MODULE my_module
程序my_prog
使用my_module
隐式无
类型(my_derived_type):: x
class(my_type),allocatable :: y
x%data = 1.0
call s ub_copy(x,y)
print *,y%data
解除分配(y)
结束程序my_prog
这对于预期结果和内存分配/释放都很好。
然而,我一直在努力尝试使用Fortran 函数来完成相同的工作。
看起来像一个类似于子程序的方法定义的函数(见下文)不能简单地用作
pre> y = fun_copy(x)
和我的gfortran编译器(v5.0.0)抱怨:
错误:赋值给(1)处的可分配多态变量尚未支持
我在这里和那里看到,编译器不支持这样的赋值。等待这个,我试图通过定义我自己的赋值运算符(=)来解决这个问题。以下代码有效:
MODULE my_module
类型:: my_type
real ::数据
endtype my_type
类型,extends(my_type):: my_derived_type
结束类型my_derived_type
接口赋值(=)
模块过程myassign
结束界面
CONTAINS
函数fun_copy(旧)结果(新)
隐式无
class(my_type),intent( in):: old
class(my_type),allocatable :: new
allocate(new,source = old)
new%data = new%data + 1
end function fun_copy
子程序myassign(new,old)
class(my_type),intent(in):: old $ b $ class(my_type),allocatable,intent(out):: new
allocate(new,source = old)
结束子程序
END MODULE my_module
PROGRAM my_prog
使用my_module
隐含无
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
它的工作原理的确如此, code> x 创建为 y
。
然而,检查这个简单测试程序的内存预算(我在OS X上使用了 Instrument 软件),似乎有些内存在其结束之前未被释放。
我怀疑 copy 函数和赋值子例程都分配了内存,而且我只释放了一次,剩下一次分配。
由于我打算在更复杂的代码中使用这样的例程很多次,所以我非常关心内存分配/释放。
当然,我可以使用程序的子程序版本,但如果有办法,我更喜欢功能版本。 b
$ b
有没有办法处理这样的问题?
指针?
模块my_module
隐式无
型:: my_type
real :: data
包含
过程:: sub_copy
过程:: fun_copy_ptr
过程:: fun_copy_alloc
过程,pass(this):: my_assign
generic :: assignment(=)=> my_assign
结束类型my_type
类型,extends(my_type):: my_derived_type
结束类型my_derived_type
包含
子例程sub_copy(this,new)
class(my_type),intent(in):: this $ b $ class(my_type),allocatable,intent(out):: new
allocate( new,source = this)
new%data = new%data + 1
end子程序sub_copy
函数fun_copy_alloc(this)result(new)
class(my_type),intent(in):: this $ b $ class(my_type),allocatable :: new
allocate(new,source = this)
new%data =新%数据+ 1.0
结束函数fun_copy_alloc
函数fun_copy_ptr(this)结果(新)
class(my_type),intent(in):: this
class(my_type),pointer :: new
allocate(new,source = this)
new%data = new%data + 1.0
结束函数fun_copy_ptr
子程序my_assign(new,this)
class(my_type),intent( in):: this
class(my_type),allocatable,intent(out):: new
allocate(new,source = this)
结束子程序
结束模块my_module
程序my_prog
使用my_module,仅:&
my_type,&
my_derived_type
$ b隐式无
类型(my_derived_type):: x
class(my_type),allocatable :: y $ b $ class(my_type),指针: :y_ptr => null()
x%data = 1.0
!案例1
调用x%sub_copy(y)
print *,y%data
deallocate(y)
!案例2
y_ptr => x%fun_copy_ptr()
print *,y_ptr%data
deallocate(y_ptr)
!案例3
分配(y,源= x%fun_copy_alloc())
print *,y%data
解除分配(y)
结束程序my_prog
I am quite a beginner in OOP with Fortran and I am trying to write a program with procedures that deal with polymorphic variables as arguments. Although my original code is much more complicated (many procedures, several derived types etc), I could isolate a simple example of my problem, say: I have a procedure that copies a polymorphic variable and slightly modifies this copy.
I was able to successfully write my test program using a subroutine:
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
This performs nicely both regarding the expected result and the memory allocation/deallocation.
However, I have been fighting for days trying to make working a Fortran function that would do the same job.
It seems that a function defined in a similar way to the subroutine (see here after) cannot be used simply as
y = fun_copy(x)
and my gfortran compiler (v5.0.0) complains:
Error: Assignment to an allocatable polymorphic variable at (1) is not yet supported
I have read here and there that indeed such assignment is not supported by my compiler. Waiting for that, I have tried to work that around by defining my own assignment operator (=). The following code works:
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
It works in the sense that indeed, a copy of x
is created as y
.
However, inspecting the memory budget of this simple test program (I use the Instrument software on OS X), it appears that some memory is not deallocated before the end of it.
I suspect that the copy function and the assignment subroutine both allocate memory and that I only free one occurrence, leaving one allocated.
As I intend to use such a routine a large number of times in a much more complicated code, I am really concerned about memory allocation/deallocation. Of course, I can use the subroutine version of the program, but if there is a way, I would prefer the function version.
Is there a way to deal with such a problem?
Have you tried using pointers?
module my_module
implicit none
type :: my_type
real :: data
contains
procedure :: sub_copy
procedure :: fun_copy_ptr
procedure :: fun_copy_alloc
procedure, pass (this) :: my_assign
generic :: assignment(=) => my_assign
end type my_type
type, extends(my_type) :: my_derived_type
end type my_derived_type
contains
subroutine sub_copy(this, new)
class(my_type), intent (in) :: this
class(my_type), allocatable, intent (out) :: new
allocate(new, source=this)
new%data = new%data + 1
end subroutine sub_copy
function fun_copy_alloc(this) result (new)
class(my_type), intent(in) :: this
class(my_type), allocatable :: new
allocate(new, source=this)
new%data = new%data + 1.0
end function fun_copy_alloc
function fun_copy_ptr(this) result (new)
class(my_type), intent(in) :: this
class(my_type), pointer :: new
allocate(new, source=this)
new%data = new%data + 1.0
end function fun_copy_ptr
subroutine my_assign(new, this)
class(my_type), intent(in) :: this
class(my_type), allocatable, intent(out) :: new
allocate(new, source=this)
end subroutine
end module my_module
program my_prog
use my_module, only: &
my_type, &
my_derived_type
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y
class(my_type), pointer :: y_ptr => null()
x%data = 1.0
! Case 1
call x%sub_copy(y)
print *, y%data
deallocate(y)
! Case 2
y_ptr => x%fun_copy_ptr()
print *, y_ptr%data
deallocate(y_ptr)
! Case 3
allocate( y, source=x%fun_copy_alloc() )
print *, y%data
deallocate(y)
end program my_prog
这篇关于Fortran多态,函数和分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!