7

C ++ / CLIIDisposableは、refクラスにデストラクタを実装するときに、スキャフォールディングを生成するのに役立ちます。また、デストラクタを実装していないが、クラスにを実装するメンバー変数があるIDisposable場合IDisposableは、クラスに再び自動的に実装されます。IDisposableこれは非常に便利で、C#での処理方法よりもはるかに優れています。

msclr::com::ptr(RCWを含むスマートポインター)を保持するrefクラスを実装するときに、この動作に遭遇しました。

ref class Test /* : IDisposable added by the compiler */
{
  msclr::com::ptr<IWhatever> _aComObject;
}

私の特定のケースでは、クラスによって参照されるCOMオブジェクトは、一部のアンマネージリソースを「ロック」せず、CLRが認識できないアンマネージメモリを事実上消費します。したがって、クラスを実装しないことで、refクラスのユーザーを混乱させないようにしたいと思いますIDisposable。代わりに、GC APIを使用して適切なメモリプレッシャーを追加することにより、CLRにCOMオブジェクトの存在を認識させたいと思います。

したがって、問題は次のとおりです。IDisposableデストラクタを実装していないが、IDisposableメンバー変数を保持しているrefクラスでの実装を抑制する方法はありますか?

注意:これは、クラスのユーザーが基になるCOMオブジェクトを決定論的に破棄できないため、間違ったことになることがよくありますが、特定の状況を考えると、公開するIDisposableと、refクラスのユーザーを混乱させる可能性があります。問題のrefクラスを破棄する必要はありません。

1つのオプションは、デストラクタなしでmsclr :: com::ptrのバリアントを実装することだと思います。

IDisposableの自動追加を抑制する他の方法をいただければ幸いです。ありがとう。


答え

_aComObjectmsclr :: com :: ptr()へのハンドルとして宣言しmsclr::com::ptr<IWhatever>^ます。その場合、コンパイラはTestcom ptrオブジェクトの「所有者」であるとは見なさず、Testが削除されたときにそれを破棄しません。

4

2 に答える 2

1

IDispose の実装を回避する理由に同意するかどうかはわかりませんが、クラスに IWhatever* を格納するだけではどうですか。その後、コンパイラは IDisposable 実装を生成しません。

デストラクタの動作が望ましくない場合、com::ptr ラッパーを購入するメリットは何ですか? 本当に必要な場合は、いつでもスタック上で com::ptr を宣言し、任意のメソッドでメンバー ポインターを割り当てることができます。

于 2009-02-06T01:32:34.087 に答える