UPDATE: Zmodyfikowany kod korekcji błędu, jeśli ktoś jest zainteresowany to jako przykładArray rozszerzonych obiektów w Fortran
próbuję się zawiesić OOP w Fortran, ale mam pewne problemy . Każda pomoc będzie wysoko ceniona:
Chcę przechowywać wskaźniki do obiektów rozszerzonych przez klasę abstrakcyjną w tablicy, a następnie wywołać jeden z podprogramów abstrakcyjnych dla tych obiektów. Jednakże pojawia się błąd kompilacji, gdzie staram się wywołać podprogram:
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)
Mam klasy abstrakcyjnej w Body.f90 z dwóch odroczonych procedur:
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
potem dostałem prostą klasę z tablicą wskaźników, która powinna przechowywać różne obiekty rozszerzające abstrakcyjną klasę Body
, Body_set.f90 (Uwzględniłem wszystkie używane podprogramy, ale ważne jest to na dole):
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
Ważna część 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
O dobroci! To był śmieszny błąd z mojej strony. Wielkie dzięki! :) – Paul