2017-10-07 19 views
1

ありがとうございました。私はいくつかのVS2013コードを新しくしています。これは、C++といくつかのMicrosoft固有の拡張機能を組み合わせたものです。 )管理対象クラスに管理対象外/非管理対象メンバーを追加する

1:コードは、今、私は質問がある

ref class Foo { 
    Bar^bar_; 
    Unmanaged* ptr_; // somewhere else, ptr = new Unmanaged(); 
    ~Foo() { 
     this->!Foo(); 
    } 
    !Foo() { 
     delete ptr_; 
     // do I need anything to deal with bar_? 
    } 
}; 

を行うことができますようにそれはそうオンライン検索から、管理されていないメンバーを追加する必要があると思い

ref class Foo { 
    Bar^ bar_; // somewhere else, bar_ = gcnew Bar... 
}; 

のようなクラスを持っていますこのファイナライザ/デストラクタは行く方法ですか?

2)bar_のために余分なものを書く必要がありますが、ファイナライザ/デストラクタを明示的に記述していますか?

3)もっとクリーンな方法がありますか?

答えて

3

1)このファイナライザ/デストラクタは行く方法ですか?

はい。

2)私は、スニペットから明らかであるbar_

何のための余分なものを書く必要があります。しかし、Barクラスが使い捨てである場合は、おそらくdelete bar_;をデストラクタに追加する必要があります。ファイナライザではありません。そして、他のコードへの参照を渡した場合、この参照がBarオブジェクトを使用している最後のものであることを確かめることはできません。

3)もっとクリーンな方法がありますか?

いいえその他の方法があります。たとえば、デストラクタを追加しないようにすることができます。クラスを使用すると、クラスを呼び出す負担がかかります。通常はC#またはVB.NETコードであるため、usingステートメントを使用するか、Dispose()を明示的に呼び出す必要があります。彼らはしばしば忘れることに留意してください。または、それを呼び出す良い方法がありません。

Fooのインスタンスをたくさん作成することが期待されていない場合、Unmanagedクラスがメモリを少ししか使用しない場合は、ファイナライザで十分です。 Fooオブジェクトがアプリの生涯にわたって生きることが予想される場合、かなり一般的ですが、処分は無意味です。たとえそれが多くのメモリを使用しても、GC :: AddMemoryPressure()はかなり良い選択肢です。クラスを使いやすくします。

また、Unmanagedポインタを独自のクラスにラップすることでFooにファイナライザが不要になることも考えられます。 .NETのSafeHandleクラスのパターンに沿って、SafeBufferは最も近いものです。しかし、C++/CLIのラッパーでは、特に、deleteの失敗は隠蔽したくありません。

しかし、あなたが持っているものは、仕事を終わらせます。

+0

ありがとう@ hans-passant!私は純粋なC++であったが、VS2013を初めて使用して以来、もう1つのフォローアップがあります。クラスが使い捨てであるかどうかを確認するにはどうすればよいですか?それらはすべて宣言に明白ですか?私はPOD( 'bool'など)、'配列^'、' String^'のようなものも見ています。たとえば、' ref class array'のソースに到達できません。 – hahaha

+1

IDisposableインターフェイスを実装するとき。オブジェクトブラウザは、あなたにそれを伝えることができます。 PODは決してしません。 –

関連する問題