指向对象的类型变量 - Fortran

时间:2017-08-18 16:20:32

标签: pointers fortran

据我了解,用户派生类型的定义不能包含target属性。例如,这是不允许的:

type TestType
    integer, target :: t
end type

然而,他们成为指针是好的:

type TestType2
    integer, pointer :: p
end type

我的问题是,如何使用指针指向对象的类型变量?例如,如果我希望type(TestType2)的对象将其p变量指向type(TestType)的{​​{1}}变量的对象,我该如何处理?例如:

t

谢谢!

2 个答案:

答案 0 :(得分:2)

中没有任何意义
type TestType
    integer, target :: t
end type

因为type(TestType)的值很容易出现在上下文中 它们不能成为指针的目标。

在@roygvib评论时,您必须将target属性赋予整个对象变量:

type(TestType), target :: tt

然后你可以指向它的任何组件。

我可以想象,可以允许将target属性赋予类型声明中的可分配结构组件,但不允许这样做。当然,这对常规组件来说没有多大意义。

答案 1 :(得分:0)

感谢@roygvib和@Vladimir F,我没有意识到赋予整个对象变量target属性将允许我指向它的任何组件。这很有效。

对于后人来说,由于我的用例比上面的例子稍微复杂一些,我想我会发布一个更具代表性的例子,说明我想要实现的目标。我正在创建一个包含GridCellRiver s的网格系统,每个GridCell都有一个Rivers数组,每个River也有一系列Rivers流入(inflows) - 这些流入将是以前创建并存储在GridCell河流阵列中的Rivers。我想使用指针,以便流入可以指向特定GridCell的河流阵列中的相应河流。

增加的复杂性是River本身是一个抽象类型,由不同的SubRiver扩展(下例中的SubRiver1和SubRiver2)。我希望河流和流入的数组为class(River)(即多态),并且在没有Fortran抱怨多态数组的情况下实现这一目的的唯一方法是创建另一个具有多态的用户派生类型RiverElement用于存储河流的class(River), allocatable :: item属性(请参阅here)。

最后,因为我无法设置inflows数组,使得每个项目都是一个指针(设置inflows(:)作为指针生成指针数组,而不是指针数组),我不得不创建另一个用户派生类型,专门用于存储指向Rivers的指针。

这是包含所有类型定义的模块:

module TestModule
    implicit none

    type :: RiverPointer
        class(River), pointer :: item => null()
    end type

    type, abstract :: River
        type(RiverPointer), allocatable :: inflows(:)
        integer :: id
    end type

    type :: RiverElement
        class(River), allocatable :: item
    end type

    type :: GridCell
        type(RiverElement), allocatable :: rivers(:)
    end type

    type, extends(River) :: SubRiver1
    end type

    type, extends(River) :: SubRiver2
    end type

end module

这是一个测试程序,显示它有效:

program main
    use TestModule
    implicit none

    type(GridCell), target :: gc
    type(SubRiver1) :: sr1
    type(SubRiver2) :: sr2
    type(SubRiver1) :: sr3

    sr1%id = 1
    sr2%id = 2
    sr3%id = 3
    allocate(gc%rivers(3))
    allocate(gc%rivers(1)%item, source=sr1)
    allocate(gc%rivers(2)%item, source=sr2)
    allocate(gc%rivers(3)%item, source=sr3)

    allocate(sr3%inflows(2))
    sr3%inflows(1)%item => gc%rivers(1)%item
    sr3%inflows(2)%item => gc%rivers(2)%item

    write(*,*) sr3%inflows(1)%item%id           ! 1
    write(*,*) sr3%inflows(2)%item%id           ! 2
    gc%rivers(1)%item%id = 100
    write(*,*) sr3%inflows(1)%item%id           ! 100
end program

全部谢谢!