Understanding Fortran extends types and override

后端 未结 1 1674
长发绾君心
长发绾君心 2021-02-04 06:34

I am trying to understand the object-oriented concepts in Fortran 2003 standards (or later). I have some knowledge in C++ so I think there are some common ideas between these tw

相关标签:
1条回答
  • First some comments/answers to your questions:

    • You can declare a type bound procedure being deferred. Then you have to define its signature (interface) only without a specific implementation. The type containing the deferred procedure must be declared abstract. Such types can not be instantiated. All extending types must provide an implementation for the given procedure, unless they are themselves abstract.

    • In order to provide an implementation for a deferred procedure in an extending type, you just declare the procedure in the extending type and provide an implementation for it.

    • You can not turn a public procedure of a given type into a generic in an extending type. You can, however, define a generic already in the base type and extend it in its derived types.

    • The pass attribute is set by default, so that the first argument of the procedure will be the type instance. You can, however, specify it to make it more explicit. Additionally, you could use it in the form PASS(ARGNAME) to specify, which argument (ARGNAME) should be the instance. This argument needs not be the first one in the procedure.

    Below you find a self containing example, which should contain all the features you asked for:

    module basis_module
      implicit none
    
      type, abstract :: Basis
        integer :: NBasis
      contains
        procedure(allocBasisR1Interface), deferred :: allocateBasisR1
        generic :: allocateBasis => allocateBasisR1
      end type Basis
    
      interface 
        ! Interface for real basis allocation
        subroutine allocBasisR1Interface(self, array)
          import
          class(Basis), intent(inout) :: self
          real, intent(in) :: array(:)
        end subroutine allocBasisR1Interface
      end interface
    
    end module basis_module
    
    
    module extension_module
      use basis_module
      implicit none
    
      type, extends(Basis) :: GridBasis
      contains
        ! Extending the mapping allocateBasis => allocateBasisR1 of
        ! the parent type.
        generic :: allocateBasis => allocateBasisC1
        procedure :: allocateBasisC1
        ! Implementation for the deferred procedure in Basis
        procedure :: allocateBasisR1
      end type GridBasis
    
    contains
    
      subroutine allocateBasisR1(self, array)
        class(GridBasis), intent(inout) :: self
        real, intent(in) :: array(:)
    
        self%NBasis = size(array)
        print *, "GridBasis:allocateBasisR1"
    
      end subroutine allocateBasisR1
    
    
      subroutine allocateBasisC1(self, array)
        class(GridBasis), intent(inout) :: self
        complex, intent(in) :: array(:)
    
        self%NBasis = size(array)
        print *, "GridBasis:allocateBasisC1"
    
      end subroutine allocateBasisC1
    
    end module extension_module
    
    
    program test
      use extension_module
      implicit none
    
      type(GridBasis) :: mybasis
      real :: myRealArray(10)
      complex :: myComplexArray(5)
    
      call mybasis%allocateBasis(myRealArray)
      call mybasis%allocateBasis(myComplexArray)
    
    end program test
    
    0 讨论(0)
提交回复
热议问题