Note that there are some explanatory texts on larger screens.

plurals
  1. POArray of extended objects in Fortran
    primarykey
    data
    text
    <p><strong>UPDATE</strong>: Modified the code correcting the mistake, if anyone is interested in it as an example</p> <p>I'm trying to get the hang of OOP in Fortran, but got some problems. Any help will be highly appreciated:</p> <p>I want to store pointers to objects extended by an abstract class in an array and then call one of the abstract subroutines for these objects. However I get an compilation error where I'm trying to call the subroutine:</p> <pre><code>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 &amp; 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) </code></pre> <p>I've got a abstract class in <strong>Body.f90</strong> with two deferred procedures:</p> <pre><code>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 </code></pre> <p>Then I've got a simple class with an pointer array that should keep different objects that extends the abstract <code>Body</code> class, <strong>Body_set.f90</strong> (I've included all used subroutines, but the important one is at the bottom):</p> <pre><code>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 =&gt; 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 =&gt; self%bodies(i)%obj end function get_body </code></pre> <p><strong>Important part of Body_set.f90</strong>:</p> <pre><code> !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 =&gt; 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 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload