2017-08-18 6 views
1

私が理解するように、ユーザー派生型の定義にはtarget属性を含めることはできません。例えばは、これが許可されていません。オブジェクトの型変数を指す - Fortran

type TestType2 
    integer, pointer :: p 
end type 

は私の質問、そして、どのように1は、オブジェクトのを指すようにポインタを使用することができている:彼らはポインタであるために

type TestType 
    integer, target :: t 
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

"type(TestType)、target :: tt"というターゲット属性をttに付けるのはどうでしょうか?次に、ttのすべてのコンポーネントもターゲット属性を想定していると思います(つまり、?)ので、他のポインタで指し示すことができます。 – roygvib

答えて

2

type(TestType)の値を簡単に 彼らはポインタの対象にならない状況で出てくる可能性があるため

type TestType 
    integer, target :: t 
end type 

にはほとんど意味があるでしょう。 @roygvibコメントとして

、あなたは全体のオブジェクト変数にtarget属性を与えることがあります。そして、あなたはそのコンポーネントのいずれかへのポインタを作ることができます

type(TestType), target :: tt 

私は、型宣言の中で割り当て可能な構造体コンポーネントにtarget属性を与えることができるとは思っていましたが、それは許されません。確かに、これは普通のコンポーネントにとっては意味がありません。

0

ありがとうございました@roygvibと@Vladimir F、オブジェクト全体に変数targetを与えると、そのコンポーネントのいずれかを指すことができるようになりました。それは完璧に働いた。

私の使用例は上記の例より少し複雑だったので、私は達成しようとしていたもののより代表的な例を投稿したいと思っていました。 GridCellRiverを含むグリッドシステムを作成しました。各GridCellには河川の配列があり、各河川には(inflows)に流入する河川の配列もあります。これらの流入は、以前に作成されて保存された川ですGridCellの川の配列で私は流入が特定のGridCellの川の配列の対応する河川を指し示すことができるようにポインタを使いたいと思っていました。

River自体が抽象型であり、異なるSubRiver(以下の例ではSubRiver1とSubRiver2)によって拡張されています。私は、河川と流入物の配列をclass(River)(すなわち多形性)にしたいと思っていました。そして、多形性配列についてFortranが不平を言わずに達成するための唯一の方法は、川を保存するためのポリモーフィックなclass(River), allocatable :: itemプロパティを持つ別のユーザー由来型RiverElementhere)。

最後に、inflowsの配列を各項目がポインタであるように設定できなかったため(ポインタがポインタの配列ではなくポインタ配列になるようにinflows(:)を設定する)、別のユーザー派生型川へのポインタを格納するためのものです。

は、ここですべての型定義を持つモジュールです:

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 

おかげですべての!

関連する問題