Ich bin ein ziemlich Anfänger in OOP mit Fortran und ich versuche, ein Programm mit Prozeduren zu schreiben, die polymorphe Variablen als Argumente behandeln. Obwohl mein ursprünglicher Code viel komplizierter ist (viele Prozeduren, mehrere abgeleitete Typen usw.), könnte ich ein einfaches Beispiel meines Problems isolieren, sagen wir: Ich habe eine Prozedur, die eine polymorphe Variable kopiert und diese Kopie geringfügig modifiziert.Fortran-Polymorphie, Funktionen und Zuweisung
MODULE my_module
type :: my_type
real :: data
endtype my_type
type, extends(my_type) :: my_derived_type
end type my_derived_type
CONTAINS
subroutine sub_copy(old,new)
implicit none
class(my_type), intent(in) :: old
class(my_type), allocatable, intent(out) :: new
allocate(new, source = old)
new%data = new%data + 1
end subroutine sub_copy
END MODULE my_module
PROGRAM my_prog
use my_module
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y
x%data = 1.0
call sub_copy(x,y)
print*,y%data
deallocate(y)
END PROGRAM my_prog
Dies führt schön sowohl in Bezug auf das erwartete Ergebnis und die Speicherzuweisung/Freigabe: Verwendung eines Subroutine
konnte ich erfolgreich mein Testprogramm schreiben.
Allerdings habe ich seit Tagen kämpfen, um zu versuchen, ein Fortran Funktion arbeiten, die die gleiche Arbeit machen würde.
Es scheint, dass eine Funktion in ähnlicher Weise an das Unterprogramm definiert (siehe hier nach) nicht einfach als
y = fun_copy(x)
und meinem gfortran Compiler (v5.0.0) verwendet wird, klagt:
Error: Assignment to an allocatable polymorphic variable at (1) is not yet supported
Ich habe hier und da gelesen, dass eine solche Zuordnung tatsächlich von meinem Compiler nicht unterstützt wird. Darauf wartend habe ich versucht, das zu umgehen, indem ich meinen eigenen Zuweisungsoperator (=) definiert habe. Der folgende Code funktioniert:
MODULE my_module
type :: my_type
real :: data
endtype my_type
type, extends(my_type) :: my_derived_type
end type my_derived_type
interface assignment(=)
module procedure myassign
end interface
CONTAINS
function fun_copy(old) result(new)
implicit none
class(my_type), intent(in) :: old
class(my_type), allocatable :: new
allocate(new, source = old)
new%data = new%data + 1
end function fun_copy
subroutine myassign(new,old)
class(my_type), intent(in) :: old
class(my_type), allocatable, intent(out) :: new
allocate(new, source=old)
end subroutine
END MODULE my_module
PROGRAM my_prog
use my_module
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y
x%data = 1.0
y = fun_copy(x)
print*,y%data
deallocate(y)
END PROGRAM my_prog
Es arbeitet in dem Sinne, dass in der Tat, eine Kopie von x
als y
erstellt. Das Speicherbudget dieses einfachen Testprogramms (ich benutze die Instrument Software auf OS X), aber es scheint, dass einige Speicher nicht vor dem Ende freigegeben wird. Ich vermute, dass die Kopie Funktion und die Zuweisung Unterprogramm sowohl Speicher zuweisen und dass ich nur ein Vorkommen frei, so dass eine zugewiesen.
Da ich beabsichtige, eine solche Routine eine große Anzahl von Malen in einem viel komplizierteren Code zu verwenden, bin ich wirklich besorgt über Speicherzuweisung/Freigabe. Natürlich kann ich die Unterroutine Version des Programms verwenden, aber wenn es einen Weg gibt, würde ich die Funktion Version bevorzugen.
Gibt es eine Möglichkeit, mit einem solchen Problem umzugehen?
In Ihrem Funktionsbeispiel meinen Sie 'y = fun_copy (x)', denke ich. Als weitere Problemumgehung 'allocate (y, source = fun_copy (x))' ', aber das ist nicht so attraktiv. Es wäre interessant zu sehen, ob das Gleiche weiter besteht. – francescalus
@francescalus Ja meinte ich 'y = fun_copy (x)'. Ich habe den ursprünglichen Beitrag bearbeitet und korrigiert. Außerdem habe ich gerade Ihre Problemumgehung versucht, und das Problem der Speicherzuweisung/-freigabe bleibt bestehen. Soweit ich das beurteilen kann, ändert sich nichts. – Reno
Nun, ich kenne die Antwort (noch?) Nicht, aber ich nehme an, dass wir eine definierte Zuweisung als Problem ausschließen können. – francescalus