Is it currently possible to override the structure constructor in Fortran?
号:
type(mytype) function init_mytype
integer, intent(in) :: i
は、おそらくのように書き換えなければならない機能仕様に存在しない引数の存在と意図を指定しますあなたのアプローチを使用しても、コンストラクタのオーバーライドに関する完全なものではありません。主な理由は、構造コンストラクタ#OOPコンストラクタです。いくつかの類似点がありますが、これはちょっとしたアイデアです。
初期化式で非組み込み関数を使用することはできません。定数、配列、構造体のコンストラクタ、組み込み関数のみを使用することができます。詳細は、Fortran 2003ドラフトの7.1.7初期化式を参照してください。私は完全に
type(mytype) :: x
x = mytype(0)
と
type(mytype) :: x
x = init_mytype(0)
と何MYMODモジュール内部インターフェイスのブロックを使用しての全体のポイントがあるとの本当の違いは何であるか理解していないアカウントにその事実を取る
。
まあ、正直言って違いは、巨大なものです - 最初のやり方は誤解を招きます。この関数はコンストラクタではありません(FortranにはOOPコンストラクタが一切存在しないため)、初期化子です。
- メモリ割り当て:主流のOOPコンストラクタで
を順次二つのことを行うための責任があります。
- メンバーの初期化。
異なる言語でクラスをインスタンス化する例をいくつか見てみましょう。 Javaので
:
MyType mt = new MyType(1);
非常に重要な事実が隠されている - オブジェクトが実際にクラス型のvaribaleへのポインタであるという事実。
MyType* mt = new MyType(1);
しかし、両方の言語の一方は、2つのコンストラクタ義務も構文レベルで反映されていることがわかります。C++に相当するものは使用ヒープに割り当てであろう。これはキーワードnew(割り当て)とコンストラクタ名(初期化)の2つの部分で構成されます。 のObjective-C構文では、この事実はさらに強調されています
MyType* mt = [[MyType alloc] init:1];
多くの時間は、しかし、あなたは、コンストラクタ呼び出しのいくつかの他のフォームを見ることができます。スタックC++上割り当ての場合は、実際に我々はそれを考慮することができないので、誤解を招く恐れがあり、特別な(非常に悪い)構文建設
MyType mt(1);
を使用しています。
で
パイソン
mt = MyType(1)
オブジェクトが実際にポインタと割り当ては最初の場所を取るが(シンタックス・レベルで)隠されているという事実であるという事実の両方。そしてこの方法は... __init__
と呼ばれています! O_Oそう誤解を招く。 С++のスタック割り当ては、それと比較して消えます。 =)
とにかく、言語におけるコンストラクタを持つというアイデアは、この方法のいくつかの特別な種類を使用して1文のに割り当て初期化を行う能力を意味します。そして、これが「本当のOOP」なのだと思うなら、私はあなたに悪い知らせがあります。 Even Smalltalkdoesn't have constructors。クラス自体にnew
メソッドを持たせるのは単なる規約です(メタクラスのシングルトンオブジェクトです)。 Factory Design Patternは、同じ目標を達成するために他の多くの言語で使用されています。
私は、Fortranのモジュールの概念がModula-2に触発されたことをどこかで読んでいます。 OOP機能はOberon-2からインスピレーションを受けているようです。 Oberon-2にはコンストラクタもありません。しかし、もちろん事前宣言されたプロシージャNEW(FortranのALLOCATEのように、しかしALLOCATEは文です)を使った純粋な割り当てがあります。割り当てが終わると、(実際には)初期化子を呼び出すことができます。これは通常の方法です。特別なものはありません。
だからあなたがオブジェクトを初期化するために、工場のいくつかの並べ替えを使用することができます。これは、シングルトンオブジェクトの代わりに実際にモジュールを使用したことです。それとも、(Java/C#/ ...プログラマ)は、後者がないために普通の関数の代わりにシングルトンオブジェクトのメソッドを使用する方がいいです(モジュールなし - 通常の関数を持たない方法、メソッドのみ)。
また、あなたは代わりに、タイプバインドサブルーチンを使用することができます。 init
SUBROUTINEのthis
引数のための
MODULE mymod
TYPE mytype
PRIVATE
INTEGER :: x
CONTAINS
PROCEDURE, PASS :: init
END TYPE
CONTAINS
SUBROUTINE init(this, i)
CLASS(mytype), INTENT(OUT) :: this
INTEGER, INTENT(IN) :: i
IF(i > 0) THEN
this%x = 1
ELSE
this%x = 2
END IF
END SUBROUTINE init
END
PROGRAM test
USE mymod
TYPE(mytype) :: x
CALL x%init(1)
END PROGRAM
INTENT(OUT)
は大丈夫のようです。なぜなら、このメソッドは割り当ての直後に1回だけ呼び出されるからです。この仮定が間違っていないことを制御することは良い考えです。 mytype
にいくつかのブールフラグLOGICAL :: inited
を追加するには、それは.false.
で、最初の初期化時に.true.
に設定するかどうかを確認し、再初期化への試みに何かを行います。私は間違いなくGoogle Groupsでそれについてのいくつかのスレッドを覚えています...私はそれを見つけることができません。
ありがとうございました。気を散らすエラーのためにお詫び申し上げます、それは急いでしまった例でした。 –