2017-08-18 76 views
1

據我所知,用戶派生類型的定義不能包含target屬性。例如,這是不允許的:指向對象的類型變量 - Fortran

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 

謝謝!

+0

我不太理解你的問題。你似乎知道't'組件不能成爲目標,但你仍然希望能夠有一個指針作爲目標?這是不可能的。 – francescalus

+0

對不起,我不太清楚,我基本上問是否有任何解決方法,這將明顯實現相同/類似的事情?我也很好奇爲什麼這個約束條件存在 - 我相信它一定有一個很好的理由。 –

+1

如何將target屬性附加到tt以使「type(TestType),target :: tt」?那麼,我認爲tt的所有組件都假定目標屬性也是(right?),所以它們可以被其他指針指向。 – roygvib

回答

2

會有很少感

type TestType 
    integer, target :: t 
end type 

因爲type(TestType)值可以很容易地拿出環境,即當 他們不能是指針的目標。

由於@roygvib意見,你得給target屬性整個對象變量:

type(TestType), target :: tt 

那麼你可以讓指針指向任何組件。

我可以想象,可以允許在類型聲明中給出target屬性給可分配結構組件,但這是不允許的。當然,這對於常規組件來說並不合適。

0

感謝@roygvib和@Vladimir F,我沒有意識到給整個對象變量target屬性將允許我指向它的任何組件。這工作完美。

對於後人來說,因爲我的使用案例比上面的例子稍微複雜一些,所以我想我會發佈一個更具代表性的例子來說明我想要達到的目標。我創建了一個網格系統,其中包含GridCell s和River s,每個GridCell都有一排河流,每條河流也有一排河流流入(inflows) - 這些流入將是以前創建和存儲的河流在GridCell的河流陣列中。我想使用指針,以便流入指向特定GridCell河流陣列中的相應河流。

增加的複雜性是River本身是一個抽象類型,擴展了不同的SubRiver(在下面的示例中爲SubRiver1和SubRiver2)。我希望河流和流入數組的數量爲class(River)(即多態),而沒有Fortran抱怨多態陣列的唯一方法是創建另一個用戶派生類型RiverElement,其中包含多態0123'屬性來存儲河流(請參閱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 

謝謝大家!