2013-10-06 10 views
6

Sembra che Fortran 90 non consenta costanti denominate nei tipi di dati derivati. È vero? Il seguente codice non funziona.Costanti denominate come componenti di un tipo di dati derivato

program my_prog 
implicit none 
    type :: my_type 
     integer, parameter :: a = 1 
     real(kind(1.d0)) :: b 
    end type my_type 
    type (my_type) :: complex_type 
end program my_prog 

Il compilatore dice che l'istruzione parametro non è consentita nelle definizioni di tipo derivato.

Quando rimuovo la parola chiave parameter, tutto funziona correttamente. Ma allora come posso assicurarmi che il componente a non venga modificato altrove?

+0

* ... come posso essere sicuro che 'a' non venga modificato altrove? * Intendi dire che non lo usi? : D –

+0

In Fortran 2003 ci sono molte altre possibilità. Può essere una variabile privata con metodi setter/getter. Può essere un componente protetto ... –

risposta

3

Rende la costante (il parametro) un'entità locale del programma principale anziché il tipo. Se si desidera un maggiore controllo sulla visibilità e l'ambito dell'identificatore per la costante, inserire la costante in un modulo.

+0

Grazie. offrite soluzioni alternative che risolvono il mio problema. È possibile orare un yay o un nay sul costrutto dei parametri non consentito all'interno di un tipo di dati derivato? Hai bisogno di una conformazione per sapere che non è specifico del compilatore. – user1318806

+0

È una conseguenza diretta delle regole della lingua. Non è specifico del compilatore. – IanH

5

Secondo lo standard, non è consentito. Il attributo specificatore di componente può essere solo pointer, e dimension per Fortran 90/95 (paragrafo 4.4.1), in aggiunta allocatable in Fortran 2003 (sezione 4.5.3), e inoltre codimension e contiguous per Fortran 2008 (paragrafo 4.5. 4.1).

È possibile ottenere i documenti here.

Ho riscontrato un problema simile con lo specificatore target, che non è consentito.

MODIFICA: Perché non provare i componenti private?

module typedef 
    type :: my_type 
    integer, private :: a_int = 1 
    real(kind(1.d0)) :: b 
    contains 
    procedure :: a 
    end type my_type 

contains 
    function a(complex_type) 
    class(my_type),intent(in) :: complex_type 
    integer :: a 
    a = complex_type%a_int 
    end function 
end module 

program my_prog 
    use typedef 
    implicit none 

    type (my_type) :: complex_type 

    complex_type%b = 2.d0 ! This should work 
    write(*,*) complex_type%a(), complex_type%b 

! complex_type%a_int = 3 ! This should fail 

end program my_prog 
+0

Grande! privato è la strada da percorrere. Solo un chiarimento. Nel codice di codice sopra 'class (my_type), intent (in) :: complex_type' dovrebbe invece dire 'type (my_type), intent (in) :: complex_type'. Almeno in Fortran 90! – user1318806

+0

A partire da Fortran 2003 l'argomento fittizio * deve essere polimorfico (4.3.1.3) se e solo se il tipo da definire è estensibile * ('my_type' è estensibile).Quindi usare 'type' invece di' class' genererà un errore quando si usa Fortran 2003 e versioni successive. –

2

La domanda è: perché vuoi farlo?

Immaginare, si desidera creare una matrice di 1000 valori my_type. Il risultato sarebbe che il valore di a sarebbe stato memorizzato 1000 volte. Si tratta di uno spreco di quasi 4kb di memoria (supponendo che sia int4). Il modo migliore sarebbe definire il parametro in un modulo corrispondente.

Btw, nel libro Moderna Fortran di Clerman e Spector, la regola numero 133 afferma che è necessario definire ogni tipo derivato nel proprio modulo. Questo sarebbe un posto fantastico per una tale costante.

+0

Non avrò più di una copia. Lo sto usando nel modo in cui useresti enumerare in c. Ho un sistema di equazioni differenziali. Invece di fare riferimento al vettore come 'Y (0), Y (1)' ecc. Voglio riferirgli come 'Y (var1), Y (var2)' e così via. 'var1, var2' e così via saranno parametri costanti nel nuovo tipo di dati di tipo. – user1318806

0

È possibile definirlo come privato e produrre una funzione get(), ma non una funzione set(). In questo modo i tuoi dati saranno ben incapsulati.

Problemi correlati