同样,我可能会对如何(或可以)在Fortran中使用类型感到奇怪。
基本上,到目前为止,我拥有的是具有han界面的抽象类型 AbsBase
。现在,我可以多次扩展此类型,从而在子类型上定义sub
的不同定义,例如
基本模块
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
Child 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
Child 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
它实际上可以编译(这对我来说很令人惊讶),但是显然会导致 Segmentation Fault ,因为我在任何地方都没有定义子例程。如果我理解正确,那么我得到了type(BaseWrap) :: Child(2)
的指针数组,这些指针指向抽象类型AbsBase
的接口。现在如何从工作示例定义两个子例程?那有可能吗?
谢谢!
答案 0 :(得分: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 :(得分:1)
当那些子例程与类型,我们的数据等有某种联系时,您的设计就很好。您只需要定义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