I have a code similar to:
Module C_sys
use class_A
implicit none
Private
Type, public :: C_sys_type
private
logical :: Ao_set = .false.
type(A) :: Ao
Contains
Private
Procedure, public :: get_Ao
Procedure, public :: set_Ao
End Type C_sys_type
interface C_sys_type
Procedure C_sys_type_constructor
end interface C_sys_type
Contains
type(C_sys_type) elemental function C_sys_type_constructor(Ao) result(C_sys)
type(A), intent(in), optional :: Ao
C_sys % Ao = Ao
C_sys % Ao_set = .true.
end function C_sys_type_constructor
type(A) elemental function get_Ao
class(C_sys_type), intent(in) :: this
get_Ao = this % Ao
end function get_Ao
subroutine set_Ao(this, Ao)
class(C_sys_type), intent(inout) :: this
type(Ao), intent(in) :: Ao
this % Ao = Ao
this % Ao_set = .true.
end subroutine set_Ao
End Module C_sys
I am not sure where in the subroutine set_Ao , type(Ao), intent(in) :: Ao should be left like this or instead to have class(Ao), intent(in) :: Ao. I know that class(Ao) is making the variable polymorphic and accessing the data type of A. But I don't know when it has to be used one or the other.
Thanks.
If you want to be able to bind a function/subroutine to a derived type (and for that routine to be able to access/modify the members of an instance of that type, which is the usual use-case; referred to as "PASS
ing" a variable), you need to meet the following conditions:
TYPE
definition must contain an appropriate PROCEDURE
line (either with PASS
explicitly stated, or there by-default whenever NOPASS
is not specified).TYPE
in question, which must be declared in the argument list with CLASS
(subject to all the restrictions that entails).
CLASS
for this is that some other TYPE
might "extend" your TYPE
, which would mean it inherits its members - this can only work if the member routines are data-polymorphic.I've attempted to modify your provided code sample into something representative of what I think you actually meant, but which actually compiles, to hopefully demonstrate correct usage.
module c_sys
implicit none
private
type, public :: a
integer :: i
end type
type, public :: c_sys_type
private
logical :: ao_set = .false.
type(a) :: ao
contains
private
procedure, public :: get_ao
procedure, public :: set_ao
end type c_sys_type
interface c_sys_type
procedure c_sys_type_constructor
end interface c_sys_type
contains
type(c_sys_type) elemental function c_sys_type_constructor(ao) result(c_sys)
type(a), intent(in), optional :: ao
c_sys % ao = ao
c_sys % ao_set = .true.
end function c_sys_type_constructor
type(a) elemental function get_ao(this)
class(c_sys_type), intent(in) :: this
get_ao = this % ao
end function get_ao
subroutine set_ao(this, ao)
class(c_sys_type), intent(inout) :: this
type(a), intent(in) :: ao
this % ao = ao
this % ao_set = .true.
end subroutine set_ao
end module c_sys
TYPE A
and TYPE AO
were defined in the CLASS_A
module you haven't provided. I've declared a dummy type in my version.Things can get more complex if you want to make use of NOPASS
etc., but for "normal" usage I hope this answers your question.