4.2 最終化
拡張可能構造型は“最終サブルーチン”を持つことができます。 最終サブルーチンはその型のオブジェクトが破棄される直前に自動的に呼び出されます。 ここで言う破棄には解放によるもの、手続きからの復帰によるもの、 組込み代入の左辺である場合のもの、そして INTENT(OUT) 仮引数として渡された場合によるものがあります。最終サブルーチンは一つの引数のみを持つサブルーチンでなくてはなりません。 この一つの引数は最終サブルーチンが結合されている型の通常の仮引数でなくてはなりません(INTENT(OUT) であっ てはなりません)。 またスカラも配列も指定可能となっていて、 その型のオブジェクトが破棄される時に最終サブルーチンが呼び出されます(引数は該当オブジェクトと同じ次元数を持ちます)。 最終サブルーチンは要素別であっても問題はありません。その場合、 他にそのためのサブルーチンを持たないのであれば、任意の次元数のオブジェクトも扱うことが可能です。 オブジェクトの次元数に対して最終サブルーチンが存在しない場合には、サブルーチンは呼び出されない点に注意してください。
最終サブルーチンは型結合手続きと同様に、CONTAINS文に続く型定義の中で宣言されます。 最終サブルーチンは FINAL 文により宣言されますが、その構文は次の通りです。
FINAL [ :: ] name [ , name ]...
ここでそれぞれの name は上記ルールを満たすサブルーチンを表します。最終サブルーチンを持つ簡単な型を以下に示します。
TYPE flexible_real_vector LOGICAL :: value_was_allocated = .FALSE. REAL,POINTER :: value(:) => NULL() CONTAINS FINAL destroy_frv END TYPE ... ELEMENTAL SUBROUTINE destroy_frv(x) TYPE(flexible_real_vector),INTENT(INOUT) :: x IF (x%value_was_allocated) DEALLOCATE(x%value) END SUBROUTINE
破棄されるオブジェクトが最終化可能な成分を持つ場合、成分を最終化する前に オブジェクト全体に対する最終サブルーチンが呼び出されます。 オブジェクトが配列の場合には個々の成分は別個に最終化されます(その際に 呼び出される最終サブルーチンは成分の次元数に対応するものであって、オブ ジェクトの次元数に対応するものではありません)。
例:
TYPE many_vectors TYPE(flexible_real_vector) scalar TYPE(flexible_real_vector) array(2,3) CONTAINS FINAL :: destroy_many_vectors_1 END TYPE ... SUBROUTINE destroy_many_vectors_1(array1) TYPE(many_vectors) array1(:) PRINT *,'Destroying a',SIZE(array1),'element array of many vectors' END SUBROUTINE ... TYPE(many_vector) mv_object(3)mv_object が破棄される際にはまず‘destroy_many_vectors_1’ が mv_object を引数として呼び出され、以下が出力されます。
Destroying a 3 element array of many vectors次に配列のそれぞれの要素について、scalar と array 成分双方が destroy_frvをコールすることによって最終化されます。 これらは任意の順番で行われる可能性があります(要素別処理であるので並列に行われることもあり得ます)。
最終サブルーチンは型拡張を通じて継承されないことに注意して下さい。その代りに、
拡張型のオブジェクトが破棄される場合には最初にそのオブジェクトが持つ最終サブルーチンが呼び出され、
その後で親成分について親型の最終サブルーチンが呼び出されます。
ナビゲーション:前へ 上へ 次へ