Fortran2003 で連結リスト構造を書いています。このリンクされたリストのノードには、交互に 2 つの種類があります。リストはエッジのトポロジー リングを表し、各エッジは 2 つの頂点で囲まれ、各頂点は 2 つのエッジに接続されます。これらの構造体は抽象 NODE_T 型として宣言され、VN_T と EN_T の 2 つのサブクラスによって実装されます。VN_T は 2 つの EN_T を指し、その逆も同様です。リストはタイプ間で交互になるため、ポインターはサブクラスに格納されます。私の問題は、NEXT() および PREV() と呼ばれる VN_T および EN_T に型バインド関数 (メソッド?) を追加することであり、ポリモーフィズムを介して正しいことを行います。VN_T%NEXT() は2 つのステップでスキップし、次の VN_T を取得する必要があります (最初の VN_T とは EN_T で区切られています)。
私のタイプ/クラスの定義は次のとおりです。
TYPE, ABSTRACT :: NODE_T
INTEGER :: IENT
INTEGER :: ISIDE
INTEGER :: ISUBTYPE
INTEGER :: IPAD
CONTAINS
PROCEDURE(NEXTA), DEFERRED :: NEXT
PROCEDURE(PREVA), DEFERRED :: PREV
END TYPE NODE_T
ABSTRACT INTERFACE
FUNCTION NEXTA(PENT)
IMPORT NODE_T
CLASS(NODE_T), POINTER :: NEXTA
CLASS(NODE_T) :: PENT
END FUNCTION
FUNCTION PREVA(PENT)
IMPORT NODE_T
CLASS(NODE_T), POINTER :: PREVA
CLASS(NODE_T) :: PENT
END FUNCTION
END INTERFACE
TYPE, EXTENDS(NODE_T) :: VN_T
DOUBLE PRECISION DT
CLASS(EN_T), POINTER :: N
CLASS(EN_T), POINTER :: P
CONTAINS
PROCEDURE :: NEXT => NEXTV
PROCEDURE :: PREV => PREVV
END TYPE
TYPE, EXTENDS(NODE_T) :: EN_T
CLASS(VN_T), POINTER :: N
CLASS(VN_T), POINTER :: P
CONTAINS
PROCEDURE :: NEXT => NEXTE
PROCEDURE :: PREV => PREVE
END TYPE
next/prev ルーチンの実装はすべてほぼ同じで、next/prev と EN/VN の 4 つの組み合わせがあります。
FUNCTION NEXTE(PENT)
CLASS(NODE_T), POINTER :: NEXTE
CLASS(EN_T) PENT
NEXTE => PENT%N%N
END FUNCTION
これらの関数を呼び出すと:
CLASS(NODE_T), POINTER :: NODE1, NODE2
NODE2 => NODE1%NEXT()
次に、私のコンパイラ (Intel FORTRAN XE Composer 2011、つまり v12.0) が次のメッセージを表示します。
error #8314: If the rightmost part-name is of abstract type, data-ref shall be polymorphic [NEXT]
NODE2 => NODE1%NEXT()
---------------------------^
これに基づいて、このドキュメントは、サブクラスの実装の1つを選択するのではなく、基本クラスでプロシージャNEXTを呼び出そうとしていることを示しているようです(右側にあるNODE1の具体的なタイプに基づいて実行できるはずです)手元ですよね?)。
私は F2003 の OOP 機能に慣れていないので、Java でこのパターンのモックアップを作成し、満足のいく作業ができました。これが a) F2003 の OOP 動作の違いなのか、2) コンパイラのバグなのか、3) 頭がおかしいだけなのか、誰でも明らかにできますか...