wiki:参照型変数実装へ向けて

Version 1 (modified by dai, 13 years ago) (diff)

--

  • ポインタを扱う場面を極力無くす
  • 実体オブジェクトのコピーを繰り返すよりも高速

参照型変数を全面的に導入する言語システムは、上記のようなメリットを生じさせることができる。現状のABでは、残念ながらこれらの要望には応えることができない。メソッド内で確保されたオブジェクトを戻り値(実体コピーはNG)として扱いたければ、それをポインタ型にしなければならない。ポインタを活用しない環境を無理やり作り出すと、オブジェクトインスタンスがスタック上のあちらこちらに転がってしまうという、パフォーマンス的にあまりよろしくない状況に陥る恐れさえある。

しかし、いきなり参照型変数を導入するといっても、それがどのレベルのお話なのか、皆目検討もつかない。一般的に、オブジェクト変数すべてが参照型になっている言語は多い(C#/Javaなど…)。それら参照先のオブジェクトは高度なGCによって管理され、プログラマの負担を軽減している。しかしながら、AB5で実装する参照型変数はデフォルトの状態で扱うのが前提ではないことに注目したい。

例えば、ABで "Dim obj As Object" としたら、Object型の静的オブジェクトobjがグローバルまたはローカル領域に出来上がる。これは従来の仕様どおり。

これらの措置は下位互換を重視するのが目的ということもあるが、スコープ単位で生成・破棄が繰り返されるオブジェクトの寿命管理は、コード中のほとんどの箇所で利用したいモデルであることは間違いない。C#やJavaを採用した場合でも、GCが面倒を見てくれるからといってオブジェクトの使用範囲(寿命)を全く無視してコーディングしたほうが良いなどという推奨は誰もしないだろう。

ABの参照型変数のモデル

  • 実体生成はNew演算子によって行い、インスタンスの破棄はGCによって管理される。参照型変数に対してのDeleteは可能だが、コンパイラが警告を発する。
  • 参照型変数は値渡し・参照渡し共に可能である。生成・破棄の手法が異なることを除き、一般的なローカルオブジェクトと扱いは変わらない。
  • 関数の戻り値として、実体オブジェクト・参照型変数の違いはない。Returnステートメントに指定された値によって柔軟に対応する。

ABの参照型変数の一番のメリットは、静的オブジェクトとの相性が良いことである。静的オブジェクトを参照することもできれば、参照先のインスタンスを静的オブジェクトにコピーすることだって可能だ。

それでは、"Function test() As Object" など、関数の戻り値にオブジェクトを指定したときこの戻り値は実態オブジェクトなのか、参照型オブジェクトなのか。。。答えはどちらも正解である。

Function test() As Object
    Dim obj As Object
    ...
    Return obj
End Function

Dim LocalObj As Object
Ref RefObj As Object
LocalObj = test()
RefObj = test()

上記のコードは、具体的に言えばtest関数内で定義される静的オブジェクトobjがLocalObjまたはRefObjにコピーされるというコードである。厳密に言えば、RefObjが参照しているのは、ヒープ領域に作成されたtest関数内のobjのコピーになる。

では、オブジェクトインスタンスのコピーを一回の発生させることなく、スマートに関数の戻り値にオブジェクトを指定したいときはどのようにすれば良いのだろう。下記にコードを示す。

Function test() As Object
    Ref obj = New Object
    ...
    Return obj
End Function

Dim LocalObj As Object
Ref RefObj As Object
LocalObj = test()
RefObj = test()

ここで、LocalObjには一旦ヒープ領域に一時確保されたtest関数内objが静的オブジェクトにコピーされる。 そして、RefObjのほうは、一回もオブジェクトインスタンスのコピーが発生することなく、test関数内でNewされたObject型オブジェクトを保持している。

Refステートメント

ABの参照型変数を定義するためのステートメントとしてRefを実装する。Refステートメントは参照型変数を定義可能。基本型をRefで定義できるようにするかは未定。Refステートメントに対し、Dimステートメントで定義されたオブジェクトはスタック領域(グローバルの場合は静的領域)に作成される。

尚、Refステートメントの書式はDimのものとほぼ同じ。