Fortran中的扩展对象数组

Pau*_*aul 6 oop fortran

更新:修改错误的代码,如果有人对它感兴趣的话作为例子

我试图在Fortran中获得OOP,但遇到了一些问题.任何帮助将受到高度赞赏:

我想存储指向由数组中的抽象类扩展的对象的指针,然后调用这些对象的一个​​抽象子例程.但是我得到一个编译错误,我正在尝试调用子例程:

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)
Run Code Online (Sandbox Code Playgroud)

我在Body.f90中有一个带有两个延迟过程的抽象类:

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
Run Code Online (Sandbox Code Playgroud)

然后我有一个带有指针数组的简单类,它应该保留扩展抽象Body类的不同对象Body_set.f90(我已经包含了所有使用过的子程序,但重要的是在底部):

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

Vla*_*r F 9

错误很简单,非常清楚.您正在将子例程作为函数调用.您只能使用调用子程序call.你可能想在定义界面中使用一个函数get_mass.