もう一つ
動的オブジェクトのリストをつくってみましょう。動的オブジェクトのデータを格納するためのヒープを確保するのに標準Cライブラリ関数を使ってみようというのが目的です。Mac OS Xでは標準だというので、様子を見るのも悪くないでしょう。もちろん、Mac OS 9.x以前でも使えます。ソースコードのダウンロードはこちら。ブラウザで見たい方はこちら。
メモリーを確保する関数はmalloc()で、これを解放する関数はfree()です。C言語プログラミングではおなじみの関数です。これらは、StdCLibという名前のPEFシェアードライブラリから呼び出せるようになっています。そこで、冒頭でこれらを宣言します。
Library StdCLib
LibCall malloc { size -- addr }
LibCall free { addr -- }
一応、単独の動的オブジェクトの生成にも使えるようなポインタクラスをつくってみましょう。上位クラスはLongWordとします。4バイト幅のデータクラスのおおもとになるクラスです。ここで定義するのもポインタクラスですから、Mopsでのポインタの規約に合わせて、空っぽのときにはnilPを格納しておくようにします。ClassInit:メソッドとFreeHeap:メソッドでそれを行います。もちろん、FreeHeap:メソッドでは、free()でヒープも解放します。
オブジェクトを生成する際には、クラスの長さ+オブジェクトヘッダの長さ分のメモリーを確保して、make_objでオブジェクトデータを流し込みます。ObjPtrListクラスで各項目に対してしたのことと同じです。
Release:とReleaseObj:は同じ内容にして、まずオブジェクトにそのクラスなりのRelease:を送ってからFreeHeap:します。
:m ReleaseObj: ( -- )
nil?: Self ?EXIT \ もう解放されていたら何もしない
obj: self Release: ** \ まず動的オブジェクトにRelease:
FreeHeap: Self \ オブジェクトに割当てられていたヒープメモリ全体を解放
;m
ここで定義されたDyObjPtrクラスのインスタンスは、ポインタ版 ObjHandleとして使うことができると思います。デバッグ用のメソッドとか、シリアライズ関係のメソッドはありませんが、クラスXTを引数にしてNewObj:メッセージを送れば、動的オブジェクトが生成されますし、Obj:メッセージでオブジェクトのベースアドレスを取る方法で、メソッドをバインドすることができます。
これをリスト化するには、このDyObjPtrクラスを第一位に、(PHLIST)クラスを第二位にして二重継承した新しいクラスをつくれば、だいたいおしまいです。ただ、この継承の順番は重要です。インデックス付きのクラスをつくるには、大抵、項目となるオブジェクトのクラスを第一順位、そのタイプのリストのためのジェネリッククラスを第二順位に
多重継承するようになっています。
もちろん、リスト固有のメソッドも定義しておかなければなりません。ただ、これは、ObjPtrListクラスをつくったときの話で尽きているので、合わせて参照してください。
関連項目:
最終更新:2019年02月28日 23:06