Polymorphism in fortran

后端 未结 1 1492
醉酒成梦
醉酒成梦 2021-01-22 06:45

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.         


        
1条回答
  •  -上瘾入骨i
    2021-01-22 07:11

    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 "PASSing" a variable), you need to meet the following conditions:

    • The TYPE definition must contain an appropriate PROCEDURE line (either with PASS explicitly stated, or there by-default whenever NOPASS is not specified).
    • The function/subroutine have at least one dummy argument of the TYPE in question, which must be declared in the argument list with CLASS (subject to all the restrictions that entails).
      • The reason it needs 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
    
    • I assume your 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.

    0 讨论(0)
提交回复
热议问题