現在、Fortran で構造コンストラクターをオーバーライドすることは可能ですか?
いいえ。とにかく、あなたのアプローチを使用しても、コンストラクターのオーバーライドに関するものではありません。主な理由は、コンストラクター # OOP コンストラクターの構造体です。いくつかの類似点がありますが、これは単なる別のアイデアです。
非組み込み関数を初期化式で使用することはできません。使用できるのは、定数、配列または構造体のコンストラクター、組み込み関数などだけです。詳細については、Fortran 2003 ドラフトの 7.1.7 初期化式を参照してください。
その事実を考慮に入れると、私は完全に理解していません
type(mytype) :: x
x = mytype(0)
と
type(mytype) :: x
x = init_mytype(0)
mymod MODULE内でINTERFACEブロックを使用することの全体的なポイントは何ですか。
正直なところ、大きな違いがあります。最初の方法は誤解を招きます。この関数はコンストラクターではなく (Fortran には OOP コンストラクターがまったくないため)、初期化子です。
主流の OOP コンストラクターでは、次の 2 つのことを順番に実行します。
- メモリ割り当て。
- メンバーの初期化。
さまざまな言語でクラスをインスタンス化する例をいくつか見てみましょう。
Javaの場合:
MyType mt = new MyType(1);
非常に重要な事実が隠されています - オブジェクトが実際にはクラス型の変数へのポインタであるという事実です。C++で同等のものは、次を使用したヒープへの割り当てになります。
MyType* mt = new MyType(1);
しかし、どちらの言語でも、構文レベルでも 2 つのコンストラクターの義務が反映されていることがわかります。これは、キーワード new (割り当て) とコンストラクター名 (初期化) の 2 つの部分で構成されます。Objective-C構文では、この事実がさらに強調されます。
MyType* mt = [[MyType alloc] init:1];
ただし、多くの場合、他の形式のコンストラクター呼び出しを確認できます。スタックへの割り当ての場合、C++は特殊な (非常に貧弱な) 構文構造を使用します
MyType mt(1);
これは実際には非常に誤解を招くため、考慮できません。
Pythonで
mt = MyType(1)
オブジェクトが実際にはポインターであるという事実と、割り当てが最初に行われるという事実の両方が (構文レベルで) 隠されています。そして、このメソッドは...と呼ばれています__init__
!O_O とても誤解を招く。С++ スタック割り当ては、それと比較してフェードします。=)
とにかく、言語にコンストラクターを持つという考えは、何らかの特別な種類のメソッドを使用して、1 つのステートメントで割り当てと初期化を実行できることを意味します。そして、これが「真の OOP」だと思うなら、悪いニュースがあります。Smalltalk にもコンストラクタはありません。クラス自体にメソッドを持つのは単なる慣例new
です (それらはメタ クラスのシングルトン オブジェクトです)。Factory Design パターンは、同じ目標を達成するために他の多くの言語で使用されています。
Fortran のモジュールの概念は Modula-2 に触発されたとどこかで読みました。そして、OOP 機能はOberon-2に触発されているようです。Oberon-2 にもコンストラクタはありません。もちろん、事前に宣言されたプロシージャ NEW を使用した純粋な割り当てもあります (Fortran の ALLOCATE と同様ですが、ALLOCATE はステートメントです)。割り当て後、通常のメソッドである初期化子を呼び出すことができます (実際にはそうすべきです)。特別なことは何もありません。
したがって、ある種のファクトリを使用してオブジェクトを初期化できます。これは、シングルトン オブジェクトの代わりにモジュールを使用して実際に行ったことです。または、彼ら (Java/C#/... プログラマー) は、通常の関数がないため、通常の関数の代わりにシングルトン オブジェクト メソッドを使用すると言う方が適切です (モジュールなし - 通常の関数を持つ方法はなく、メソッドのみ)。
また、代わりにタイプバインドされた SUBROUTINE を使用することもできます。
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)
SUBROUTINEのfor this
arg は問題ないようです。init
このメソッドは、割り当て直後に 1 回だけ呼び出されることが想定されているためです。この仮定が間違っていないことを制御するのは良い考えかもしれません。LOGICAL :: inited
ブール値フラグをに追加するには、最初の初期化時にmytype
そうであるかどうかを確認.false.
してに設定し.true.
、再初期化の試行時に何か他のことを行います。Google グループでそれに関するスレッドをいくつか覚えていますが、見つかりません。