アーカイブ

Archive for 2004年4月

続々・Delphiのコレクション

Delphiにはtemplateの類いがありません。したがってコンテナには、挿入時型安全の問題と、取り出し時のバックキャストの手間が付いて回ります。

一つ試案があります。コンテナのコンストラクタにクラス参照を与えます。これを内部に保持すれば、挿入時にis演算子で動的な型チェックができます。不一致なら、例外を送出する事が出来るはずです。

クラス参照がTClassではなく、参照カウンタの基底クラス(僕は、TShareObjectと定義しています)のクラス参照であれば、さらに面白いかもしれません。Delphiのクラスメソッドは仮想化できるので、等価や比較のデフォルトオペレータを、コンテナに指定したクラス参照から自動選択させる事が出来そうです。

あんまり基礎工事にのめり込むのもアレですが、電波は受信した時に実装しないと勿体ないですしねぇ。

カテゴリー:開発 タグ:

Delphiのコレクション

Delphiに標準で付属するコレクション(コンテナ)は、配列リストと簡易的なハッシュマップのみです(動的配列もありますが、本質的には配列リストと同じ物です)。少々手札が足りないので、探して回りました。

いくつか見つかりましたが、過不足無く仕上がっているのは、DCLXぐらいのようです。Java Collection Frameworkを模したデザインで、非常に良く出来ていると思います。

しかしメモリ管理が、標準のTObjectListと同様の自動削除か、interface参照を使った参照カウンタを想定しています。僕は独自のメモリ管理を持ち込んでしまったので、整合しません。

結局諦めて、参照カウンタと自動解放プールに適合する配列リストを実装しました。追々、セットやマップも書かなきゃならなくなると思います。せっかくなので、参照カウンタの基底クラスに等価判定の仮想メソッドを追加して、コレクションから呼び出すようにしました。これでクラスの実装によっては、値ベースの検索が可能になります。同様にハッシュ算出のメソッドも用意したので、セットやマップを作る時に使えると思います。ついでに、挿入と削除で通知を起動する機構を付けました。

このぐらいやれば、コレクションを実装する手間も元が取れそうですが、ツリーセットやハッシュマップなどの面倒なやつは実装するのは気が重いです(^_^;;

カテゴリー:開発 タグ:

Delphiのinterface

言語マニュアルを読む限り、Javaのinterfaceと大差無い印象を受けますが、実際に使うとそれほど気安い物には感じられません。参照カウンタが導入されてしまったり、インターフェース毎にポインタの同値性が失われたり、直接クラス参照にアクセスする方法が無かったりと、通常のDelphiのオブジェクトととはかなり異質です。やはり、COMのために存在する機能なのでしょう。

自分の場合、Javaで自前のinterfaceを導入するケースの大半は、通知を含むコールバックの実装が目的なのですが、Delphiではメソッドポインタと言う選択肢もあります。シグニチャさえ一致していれば、全然無関係なクラスのメソッドを代入出来るので、通知には向いています。複数のメソッドのセットを強制したいのでなければ、十分interfaceの代わりになると思います。

カテゴリー:開発 タグ:

続・Delphiでメモリ管理

思索の末に、参照カウンタの明示管理を選択しました。

保持と解放を管理する共有オブジェクトの基底クラスと、NextStep風の自動解放プールを実装しました。共有オブジェクトは生成時に、必ず現在コンテキストの自動解放プールに入れる設計になっています。結果、通常try~finallyで保護する一時オブジェクトや、メソッドが返す複製も解放に留意する必要がなくなりました。また、例外発生時のみ削除が必要な中途生成オブジェクトも、完成時に保持するようにコーディングしておけば、例外安全を容易に保証出来ます。

コーディングに必要な神経は、手動Freeとガベージコレクタの中間ぐらいの感触です。

カテゴリー:開発 タグ:

Delphiでメモリ管理

思う所あって、Delphiで少し大きめのプログラムを書き始めました。
以前は漠然と、C++の代わりにはならないと思っていたのですが、JavaやRubyを使うようになって頭が柔らかくなったのかも知れません。
日に日に、悪く無いと思い始めました。

目下の懸案は、メモリ管理の煩雑さです。

  • 所有権が移動する、あるいは共有されるケースで煩雑になりやすい
  • 内部参照を返すメソッドと、複製を返すメソッドの使い分けにミスが発生しやすい
  • 例外安全に気を使うと、無駄にロジックが複雑になる事が多い

C++でも、3.0が登場する以前は似たような事をやっていたハズなのに、今ではちょっとキツいです(^_^;;

普段C++では、参照カウンタを持つ基底クラスとカウンタを管理するスマートポインタのテンプレートを使っています。
循環参照にだけは気を使いますが、ほとんど所有権を意識する必要は無いですし、例外安全を考慮してもかなり単純に記述出来ます。

Delphiでは、以下の方策が考えられます。

  • そのままがんばる
    ・・・・・・
  • interfaceを使う
    interface参照には、参照カウンタを自動管理する仕組みがあります。これには、C++のスマートポインタとほぼ同じような使用感が期待できます。ただし全域で使おうとすると、全てのクラスにinterfaceを用意する必要がありますし、クラス参照を使った技巧に制約が発生します。微妙。
  • ガベージコレクタを使う
    BoehmGCをDelphiに適応した強者を発見しました。良さそうな雰囲気ですが、ピアリソースを抱えている場合に明示廃棄を併用する必要がある事と、トラブルが出た時の対処が困難な事も想定されるので、少し腰が引けています。
  • 参照カウンタを明示的に管理する
    Objective-Cのような仕組みを、自前で用意する事も可能だと思います。コンテナ(コレクション)の類いは、参照カウンタに対応する物を自作する必要があるので、基礎工事が手間かもしれません。

あまりコードが増えると移行が大変なので、そろそろ決断が必要です。

カテゴリー:開発 タグ: