留给用户的Fortran子程序
我正试图以面向对象的方式创建一个实现所有功能的类型,除了一个应该由用户实现的功能之外 假设我有两个类型为的模块,留给用户的Fortran子程序,fortran,intel-fortran,Fortran,Intel Fortran,我正试图以面向对象的方式创建一个实现所有功能的类型,除了一个应该由用户实现的功能之外 假设我有两个类型为的模块,animal和cat扩展animal。现在我想实现一种将自定义过程传递给任何动物的方法。我不知道实现这种特性的最佳方式是什么。现在,我已经成功地让所有cat对象都有一个函数调用程序,该调用程序将子例程作为参数,但是仅当类型是显式的,或者换句话说,如果类型不是动物,并且在运行时我创建了一个cat: 动物 module animal_module implicit none
animal
和cat
扩展animal
。现在我想实现一种将自定义过程传递给任何动物的方法。我不知道实现这种特性的最佳方式是什么。现在,我已经成功地让所有cat
对象都有一个函数调用程序,该调用程序将子例程作为参数,但是仅当类型是显式的,或者换句话说,如果类型不是动物
,并且在运行时我创建了一个cat
:
动物
module animal_module
implicit none
type, abstract :: animal
private
integer, public :: nlegs = -1
contains
procedure :: legs
procedure :: speak
end type animal
interface animal
module procedure init_animal
end interface animal
contains
type(animal) function init_animal(this)
class(animal), intent(inout) :: this
print *, "Animal!"
this%nlegs = -4
end function init_animal
function legs(this) result(n)
class(animal), intent(in) :: this
integer :: n
n = this%nlegs
end function legs
subroutine speak(this, ntimes)
class(animal), intent(in) :: this
integer, intent(in) :: ntimes
integer :: i
do i = 1, ntimes
print *, "generic animal :: speak"
end do
end subroutine speak
end module animal_module
猫
module cat_module
use animal_module, only : animal
implicit none
type, extends(animal) :: cat
private
real :: hidden = 23.
contains
! something like this? maybe a pointer?
procedure :: caller
procedure :: speak
end type cat
interface cat
module procedure init_cat
end interface cat
abstract interface
subroutine sub_interface
end subroutine
end interface
contains
type(cat) function init_cat()
print *, "Cat!"
init_cat%nlegs = 4
end function init_cat
subroutine caller(this, sub)
class(cat), intent(inout) :: this
procedure(sub_interface) :: sub
print *, "caller begin", this%nlegs
call sub()
print *, "caller ended", this%nlegs
end subroutine caller
subroutine speak(this, ntimes)
class(cat), intent(in) :: this
integer, intent(in) :: ntimes
integer :: i
do i = 1, ntimes
print *, "cat :: meow"
end do
end subroutine speak
end module cat_module
主程序
subroutine ahoy
print *, "ahoy"
end subroutine ahoy
program oo
use animal_module
use cat_module
use bee_module
implicit none
class(animal), allocatable :: q
procedure(sub_interface) :: ahoy
class(cat), allocatable :: p
! THIS WON'T WORK
allocate(cat :: q)
q = cat()
call q%caller(ahoy)
! no problem with this
allocate(cat :: p)
p = cat()
call p%caller(ahoy)
end program
从动物
调用调用方
时遇到的错误是
/oo/main.F90(28): error #6460: This is not a field name that is defined in the encompassing structure. [CALLER]
call q%caller(ahoy)
-----------^
据我所知,这应该是正常的:因为animal
没有线索cat
包含caller
,所以它不会工作。我说得对吗
如何让用户实现将由调用方调用的子例程?被调用的函数应该可以访问类型,用户提供的函数应该能够修改cat
对象中的隐藏的
整数