C++/CX の shared_ptr と新しいハンドル表記 (^) の違いがよくわかりません。私が読んだことから、参照カウントとメモリ管理に関して同じことをしているようです。私は何が欠けていますか?
std::shared_ptr<Type>
//vs
Type^
C++/CX の shared_ptr と新しいハンドル表記 (^) の違いがよくわかりません。私が読んだことから、参照カウントとメモリ管理に関して同じことをしているようです。私は何が欠けていますか?
std::shared_ptr<Type>
//vs
Type^
存続期間の管理だけを考えれば、これらは同じです。aはオブジェクトshared_ptr<T>
への強力な (所有する) 参照を保持します。T
aT^
も同じです。 C++/CXmake_shared<T>
とほぼ同等です。ref new T
どこでもまたはまたはT^
と思う場合は、それで問題ありません。生涯管理はほぼ同じです。shared_ptr<T>
ComPtr<T>
CComPtr<T>
ただし、有効期間管理が内部でどのように機能するかは異なります。整形式のすべてT
の型は、インターフェイスを実装する Windows ランタイム参照型であるため、オブジェクトは内部的に参照カウント(*)されます。 任意の型をサポートし、外部参照カウントを使用します (つまり、オブジェクトの有効期間を制御するために独自の参照カウント メカニズムを割り当てます)。T^
IUnknown
T
shared_ptr<T>
弱参照の場合、shared_ptr<T>
has weak_ptr<T>
、およびT^
has WeakReference
。 WeakReference
は厳密に型指定されていませんが、厳密に型指定された参照ラッパーを簡単に記述できます。それ以外の場合、弱参照は期待どおりに機能します。弱参照のサポートはオプションです。すべての参照型が弱参照をサポートしているわけではありませんが、ほとんどはサポートしています。
(*) 例外が 1 つあります。 Platform::String^
これは、Windows ランタイムの参照型ではありませんが、さまざまな理由で特別に処理されます。T^
ただし、生涯管理に関しては他のものと同じと考えることができます。
では、なぜ Windows ランタイム型は C++/CX で帽子をかぶるのでしょうか? ライブラリ ソリューションが好まれない、shared_ptr<T>
またはComPtr<T>
使用されないのはなぜですか?
これは、具体的な実行時型へのポインター (またはハット) を実際に持っていないためです。その型が実装するインターフェイスの 1 つへのポインターを介してのみ、オブジェクトと対話できます。また、Windows ランタイムはインターフェイスまたはクラスの継承をサポートしていません。すべてのインターフェイスは から直接派生する必要がありIInspectable
、クラスの継承は COM 集約を使用してエミュレートされます。
つまり、静的なタイプ セーフを備えた自然な外観の C++ コードを生成するライブラリ ソリューションはありません。QueryInterface
関数呼び出し、派生から基底への変換、およびインターフェイス変換では、通常、正しいインターフェイス ポインターを取得するために を呼び出す必要があります。
ライブラリ ソリューション (たとえば、WRL ライブラリやほとんどすべての COM コードを参照) を使用してこれを行うことができますが、暗黙的な変換やdynamic_cast
. 帽子がないと、インターフェイス ポインターだけを処理し、自分自身を呼び出さなければならなくなりQueryInterface
ます。
(C++/CX 言語拡張が開発された理由と、C++/CLI 構文が最終的に再利用のために選択された理由に興味がある場合は、昨年のこのブログの Jim Springfield の投稿「Inside the C++/CX 設計」 . また、Marian Luparu が C++/CX について説明しているGoingNative のエピソード 3 も注目に値します。)
私が知る限り、後者は弱い参照とカスタム解放関数のサポートを欠いています。
前者はより一般的であり、(原則として) 任意の型を受け入れ、安全性とクリーン度のためにヘルパー関数を使用する必要があることに注意してくださいmake_shared
。後者は言語レベルでサポートされています。つまり、次のようなコードは C++/CX で安全です。
some_function(ref new foo(), ref new bar());
C++ では、これを行う必要があります。
// bad: if foo is allocated but bar's allocation throws, you leak!
some_function(new foo(), new bar());
// good: both never make it anywhere but into a shared_ptr, no leaks
some_function(make_shared<foo>(), make_shared<bar>());
それ以外は、確かに、同じコンセプトを実装しています。C++/CX の世界にいる場合は、単純さと統一性のために後者の構文を使用してください。標準の C++ に固執しようとしている場合、または既存のリソース管理スキームを参照カウント スキームにラップしている場合は、前者が必要になります。