一些抽象类型子程序 - Fortran

问题描述 投票:1回答:2

我可能会有一个奇怪的问题,关于我如何(或可能)在Fortran中使用类型。

基本上,我到目前为止是一个带有han接口的抽象类型AbsBase。我现在可以多次扩展这种类型bby定义Child类型,其中我有不同的sub定义,如此

Working example


基础模块

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

儿童摩洛哥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

到目前为止这么好但是如果我想定义一个类型的数组而不是有两个不同的Child类型呢?我尝试了以下内容

Non-working example (what I try to do)


基础模块

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的接口。我现在如何定义工作示例中的两个子例程?这甚至可能吗?

谢谢!

oop types fortran gfortran
2个回答
2
投票

那么,你创建的类就足以拥有你似乎在寻找的多态行为。你可以像这样测试它:

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属性的必要性,以及其他优点。


1
投票

当这些子程序对某些类型,我们的数据等有些紧张时,你的设计是好的。你只需要像罗德里戈所展示的那样定义指针。如果这些子例程实际上并不依赖于任何外部类型,并且子类型实际上只是为了保持不同的过程,则不需要这样复杂的构造。您只需将过程指针存储在一个类型中即可。

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
© www.soinside.com 2019 - 2024. All rights reserved.