2013-09-06 9 views
6

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 

Odpowiedz

9

Błąd jest prosta i bardzo jasne. Wywołujesz podprogram jako funkcję. Możesz wywołać podprogram tylko za pomocą call. Prawdopodobnie chciałeś funkcji w interfejsie definiowania dla get_mass.

+1

O dobroci! To był śmieszny błąd z mojej strony. Wielkie dzięki! :) – Paul

Powiązane problemy