手動のメモリ割り当てとポインターがまだ支配している世界 (Borland Delphi) では、一般的な問題と思われるものの一般的な解決策が必要です。
特定の時点で、オブジェクトは複数の場所 (リスト、他のオブジェクトなど) から参照できます。オブジェクトが破棄されたときに更新できるように、これらすべての参照を追跡する良い方法はありますか?
他の人に変更を通知したい場合は、「オブザーバーパターン」を実装する必要があります。Delphiは、TComponentの子孫に対してすでにそれを行っています。TComponent.FreeNotificationメソッドを呼び出して、他のコンポーネントが破棄されたときにオブジェクトに通知することができます。これは、Notificationメソッドを呼び出すことによって行われます。TComponent.RemoveFreeNotificationを呼び出すことにより、通知リストから自分自身を削除できます。このページも参照してください。
ほとんどのガベージコレクターでは、参照のリストを取得できないため、この場合は役に立ちません。インターフェイスを使用する場合、Delphiは参照カウントを実行できますが、参照を自分で追跡する必要があります。
なぜあなたがこれをやりたいのか、私にはよくわかりません。確かに、参照を使用する前に Nil ではないことを確認しますか?
Anwyays、私が検討する2つの可能な解決策は次のとおりです。
おそらく、 AddRef() および ReleaseRef() 関数をマネージャまたは参照対応クラスに追加します。これらを使用して、任意の時点で存在する参照の数を確認できます。COM はこのようにします。
参照認識クラスは、それ自体の参照カウントのみを管理します。マネージャーは Map を使用して、ポインターをカウント用の整数に関連付けることができます。
オブジェクトが破棄されたときにそれらの参照をクリアできるように、誰がオブジェクトを参照しているかを追跡しようとしていますか?それとも、いつオブジェクトを安全に破棄できるかを追跡しようとしていますか?
後者の場合、ガベージ コレクターを探しているように聞こえます。私は Delphi を扱ったことがないので、使用できる GC があるかどうかはわかりませんが、ない場合は驚くでしょう。
前者の場合、GC はおそらく役に立たないでしょう。Delphi が OOP/継承をサポートしている場合 (サポートしているかどうかは正直わかりません)、次のようなことができます (疑似コード):
// Anything that will use one of your tracked objects implements this interface
interface ITrackedObjectUser {
public void objectDestroyed(TrackedObject o);
}
// All objects you want to track extends this class
class TrackedObject {
private List<ITrackedObjectUser> users;
public void registerRef(ITrackedObjectUser u) {
users.add(u);
}
public void destroy() {
foreach(ITrackedObjectUser u in users) {
u.objectDestroyed(this);
}
}
}
基本的に、追跡対象のオブジェクトの 1 つをコレクションに追加すると、そのコレクション自体がそのオブジェクトに登録されます。オブジェクトが破棄されると (オブジェクトのデストラクタで destroy() を呼び出すと思います)、オブジェクトはコレクションに破棄されていることを通知し、コレクションが必要なことを何でもできるようにします。
残念ながら、組み込みのコレクションを使用したい場合、これは良い解決策ではありません。独自のコレクション オブジェクトを作成する必要があります (ただし、組み込みのオブジェクトをラップすることもできます)。また、オブジェクトを追跡したいすべての場所で登録していることを確認する必要があります。それは私が「幸せな」解決策と考えるものではありませんが、小規模なプロジェクトではおそらくそれほど悪くはありません. 私は主に、このアイデアが他のアイデアを生み出すのに役立つことを願っています. :)
これを望む具体的な理由はありますか?不正なポインタの問題に直面していますか、それともいつか問題になるかもしれないと考えていますか?
私見では、アプリケーションを正しく設計すれば問題にはならず、適切なパターンを使用すると本当に役立ちます。
パターンに関するいくつかの情報: