【问题标题】:Pointing to a object's type variable - Fortran指向对象的类型变量 - Fortran
【发布时间】:2017-08-18 16:20:31
【问题描述】:

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

type TestType
    integer, target :: t
end type

但是,它们可以作为指针:

type TestType2
    integer, pointer :: p
end type

那么,我的问题是,如何使用指针指向对象的类型变量?例如,如果我想让type(TestType2) 的对象使其p 变量指向type(TestType)t 变量的对象,我该怎么做呢?例如:

type(TestType) :: tt
type(TestType2) :: tt2
tt%t = 1
tt%p => tt%t

谢谢!

【问题讨论】:

  • 我不太明白你的问题。您似乎知道t 组件不能作为目标,但您仍然希望能够将指针作为目标?这是不可能的。
  • 对不起,我不太清楚,我基本上是在问是否有任何解决方法可以表面上实现相同/相似的事情?我也很好奇为什么会存在这种约束——我敢肯定它一定有充分的理由。
  • 如何将目标属性附加到 tt 使得“type(TestType), target :: tt”?然后,我认为 tt 的所有组件也假定目标属性(对吗?),因此它们可以被其他指针指向。

标签: pointers fortran


【解决方案1】:

没有什么意义

type TestType
    integer, target :: t
end type

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

作为@roygvib cmets,您必须将target 属性赋予整个对象变量:

type(TestType), target :: tt

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

我可以想象在类型声明中可以允许将目标属性赋予可分配的结构组件,但这是不允许的。当然,这对于常规组件来说意义不大。

【讨论】:

    【解决方案2】:

    感谢@roygvib 和@Vladimir F,我没有意识到给整个对象变量target 属性可以让我指向它的任何组件。效果很好。

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

    增加的复杂性是River 本身是一个抽象类型,由不同的SubRivers(下例中的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
    

    谢谢大家!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-01
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      • 2019-12-18
      • 2011-10-01
      相关资源
      最近更新 更多