gpt4 book ai didi

oop - Fortran 中的扩展对象数组

转载 作者:行者123 更新时间:2023-12-01 23:49:20 25 4
gpt4 key购买 nike

更新:修改代码纠正错误,如果有人对此感兴趣的话作为示例

我试图掌握 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)

我在 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

然后我有一个带有指针数组的简单类,它应该保留扩展抽象 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

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

最佳答案

错误很简单而且很清楚。您正在将子例程作为函数调用。您只能使用 call 调用子例程。您可能需要在 get_mass 的定义接口(interface)中使用一个函数。

关于oop - Fortran 中的扩展对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18653974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com