how example create array oop fortran

oop - example - fortran array



Matriz de objetos extendidos en Fortran (1)

ACTUALIZACIÓN : se modificó el código que corrige el error, si alguien está interesado en él como un ejemplo

Intento entender OOP en Fortran, pero tengo algunos problemas. Cualquier ayuda será muy apreciada:

Quiero almacenar punteros a objetos extendidos por una clase abstracta en una matriz y luego llamar a una de las subrutinas abstractas para estos objetos. Sin embargo, recibo un error de compilación cuando trato de llamar a la subrutina:

src/Body_set.f90(74): error #6553: A function reference is invoking a subroutine subprogram. [GET_MASS] write(*,*) "Body ", i, " - mass: ", b%get_mass() ----------------------------------------------^ src/Body_set.f90(74): error #6402: prPromoteSym : Illegal KIND & CLASS mix [GET_MASS] write(*,*) "Body ", i, " - mass: ", b%get_mass() ----------------------------------------------^ src/Body_set.f90(74): error #7021: Name invalid in this context [GET_MASS] write(*,*) "Body ", i, " - mass: ", b%get_mass() ----------------------------------------------^ compilation aborted for src/Body_set.f90 (code 1)

Tengo una clase abstracta en Body.f90 con dos procedimientos diferidos:

module Body_module implicit none private type, public, abstract :: Body private contains procedure(get_mass), deferred :: get_mass procedure(set_mass), deferred :: set_mass end type Body abstract interface function get_mass(self) result(m) import Body class(Body), intent(in) :: self double precision m end function subroutine set_mass(self, m) import Body class(Body) :: self double precision m end subroutine end interface end module Body_module

Luego tengo una clase simple con una matriz de punteros que debe mantener diferentes objetos que extienden la clase abstracta Body , Body_set.f90 (he incluido todas las subrutinas usadas, pero la más importante está en la parte inferior):

module Body_set_module use Body_module implicit none private type, public :: Body_container class(Body), pointer :: obj end type Body_container type, public :: Body_set private integer :: num_bodies type(Body_container), allocatable, dimension(:) :: bodies contains procedure :: set_body procedure :: get_body procedure :: get_num_bodies procedure :: print_summary final :: destructor end type Body_set interface Body_set procedure constructor end interface Body_set contains !Object contructor function constructor(num_bodies) result(self) class(body_set),pointer :: self integer :: num_bodies allocate(self) self%num_bodies = num_bodies allocate(self%bodies(num_bodies)) end function constructor !Returns number of bodies stored function get_num_bodies(self) result(num_bodies) class(Body_set), intent(in) :: self integer :: num_bodies num_bodies = self%num_bodies end function get_num_bodies !Set element `i` to point to `new_body` subroutine set_body(self, new_body, i) class(body_set), intent(inout) :: self class(Body), target, intent(in) :: new_body integer, intent(in) :: i self%bodies(i)%obj => new_body end subroutine set_body !Return pointer to body `i` function get_body(self, i) result(the_body) class(Body_set), intent(in) :: self integer, intent(in) :: i class(Body), pointer :: the_body the_body => self%bodies(i)%obj end function get_body

Parte importante de Body_set.f90 :

!Print a summary of all bodies subroutine print_summary(self) class(body_set), intent(in) :: self integer :: i class(Body), pointer :: b write(*,*) "Summary of ", self%num_bodies, " bodies:" do i=1,self%get_num_bodies() b => self%get_body(i) write(*,*) "Body ", i, " - mass: ", b%get_mass() end do end subroutine print_summary subroutine destructor(self) type(body_set), intent(in) :: self end subroutine end module Body_set_module


El error es simple y muy claro. Está llamando a una subrutina como una función. Puede llamar a una subrutina solo mediante call . Probablemente haya deseado una función en la interfaz de definición para get_mass .