抽象类型子例程的数组 - fortran



再次,我可能有一个奇怪的问题,即我将如何(或可以)在fortran中使用类型。

基本上,到目前为止,我是抽象类型 AbsBase带有HAN接口。现在,我可以多次扩展此类型bby bby定义儿童类型我对sub的定义不同,例如So

工作示例


基本模块

module BaseClass
    implicit none
    type, abstract :: AbsBase
    contains
        procedure(subInt), nopass, deferred :: sub
    end type
    interface
        subroutine subInt
            implicit none
        end subroutine subInt
    end interface
end module BaseClass

儿童molude 1

module ChildClass1
    use BaseClass 
    implicit noone
    type, extends(AbsBase) :: Child1
    contains
        procedure, nopass :: sub
    end type
contains
    subroutine sub
        implicit none
        print*, "Do something ..."
    end sub
end module ChildClass1

儿童molude 2

module ChildClass2
    use BaseClass 
    implicit noone
    type, extends(AbsBase) :: Child2
    contains
        procedure, nopass :: sub
    end type
contains
    subroutine sub
        implicit none
        print*, "Do something else ..."
    end sub
end module ChildClass2

程序

program test
    use ChhildClass1
    use ChhildClass2
    implicit none
    type(Child1) :: c1
    type(Child2) :: c2

    call c1%sub    ! <-- prints "Do something ...      "
    call c2%sub    ! <-- prints "Do somethhing else ..."
end program test

到目前为止,一切都很好,但是如果我想定义类型的 array ,而不是具有2种不同的 child 类型怎么办?我尝试了以下

非工作示例(我尝试做的)


基本模块

module BaseClass
    implicit none
    type, abstract :: AbsBase
    contains
        procedure(subInt), nopass, deferred :: sub
    end type
    interface
        subroutine subInt
            implicit none
        end subroutine subInt
    end interface
    type :: BaseWrap
        class(AbsBase), pointer :: p
    end type
end module BaseClass

程序

program test
    use BaseClass
    implicit none
    type(BaseWrap) :: Child(2) 
    call Child(1)%p%sub   ! <--- This should produce "Do something ..."
    call Child(2)%p%sub   ! <--- This should produce "Do something else ..."
contains
    ! Where to I define the subroutines and how would I do this?
end module ChildClass

它实际上是编译的(这对我来说是非常令人惊讶的),但是显然会导致分割故障,因为我在任何地方都没有定义子例程。如果我理解正确,那么我可以使用type(BaseWrap) :: Child(2)的一系列指针,该指针指向抽象类型AbsBase的接口。我现在如何从工作示例定义两个子例程?那甚至可能吗?

谢谢!

好吧,您创建的类足以具有您似乎正在寻找的多态性行为。您可以这样测试:

program test
  use :: BaseClass
  implicit none
  type(Child1), target :: c1
  type(Child2), target :: c2
  type(BaseWrap) :: child(2)
  child(1)%p => c1
  child(2)%p => c2
  call child(1)%p%sub    ! <-- prints "Do something ...      "
  call child(2)%p%sub    ! <-- prints "Do somethhing else ..."
end

但是,使用allocatable元素而不是pointer将删除target属性的必要性。

当这些子例程以某种方式与类型,我们的数据等等时,您的设计很好。您只需要按照罗德里戈(Rodrigo)的表现来定义指针。如果这些子例程实际上并不取决于任何外部类型,而实际上只需制定儿童类型即可执行不同的过程,则不需要如此复杂的结构。您可以将过程指针存储在单一类型中。

module subs
  implicit none
contains
    subroutine sub1
        print*, "Do something ..."
    end subroutine
    subroutine sub2
        print*, "Do something else ..."
    end subroutine
end module
  use subs
  type sub_wrap
    procedure(sub1), pointer, nopass :: sub
  end type
  type(sub_wrap) :: a(2)
  !one way
  a = [sub_wrap(sub1), sub_wrap(sub2)]
  !another way
!   a(1)%sub => sub1
!   a(2)%sub => sub2
  call a(1)%sub()
  call a(2)%sub()
end

最新更新