2016-04-13 6 views
0

私はunique_ptrを理解しようとしていますが、私にはちょっと困惑しています。一部 - - 削除されたために、私は、元のポインタが期待されるコードの2行目の後なぜunique_ptrへの未処理のポインタをキャストしてもオリジナルは削除されませんか?

PartClass * part= new PartClass; 

//The OwnerClass is a composite that excpects a unique_ptr 
OwnerClass * owner = new OwnerClass(unique_ptr<PartClass>(part); 

: 次のコードを考えてみましょう。結局のところ、あなたはunique_ptrを持つとすぐに、それは大騒ぎを引き起こし、移動する必要があります。それで、コンパイラは未加工のポインタがまだパーツオブジェクトにアクセスできるようにします。それはunique_ptrの全体のコンセプトに違反していませんか?

+0

'OwnerClass'がどこかに格納していると仮定すると、オーナーシップは' OwnerClass'に移動されるので、 'part'は削除されません。それはあなたが混乱していることですか? – TartanLlama

+0

"なぜコンパイラは未処理のポインタがパーツオブジェクトにアクセスすることを許可していますか?それはunique_ptrの全概念に違反していませんか?それは自由な世界です(もっとコンパイラに似ています)、あなたは '42を削除できます;もしあなたが好きなら、コンパイラはあなたの意図を尋ねません。もしあなたがゼロで分割したいのであれば、彼はあなたを止めません。生ポインタまたは正しい 'unique_ptr'を使用したい場合は、' law'はここにはありません。時にはハックをしてrawを使うこともできます。 – Vladp

+0

'unique_ptr ''部分を削除する 'とはどういう意味ですか?そして、もしあなたが 'part'について話しているのであれば、それは参照されたコンテンツではなく、このスコープのスタックに割り当てられ、スコープを離れるときに削除されます。 – Vladp

答えて

2

これは、ポインタを明示的に指定できるのと同じ理由で機能します。たとえば:pValueがメモリにアクセスすることができますが

std::unique_ptr<int> value = std::make_unique<int>(1); 
int* pValue = value.get(); 

はそれがそれを所有していないとメモリを削除しないでください。あなたの例では、オーナーシップは転送されていますが、生のポインタがリソースをまだ指し示しているような場合は問題ありません。

+0

Jamesさんにありがとうございました。私はunique_ptr、つまり排他的なアクセスが多すぎると予想していましたが、明らかにそうではありません。 – schulefant

+0

@schulefantそれが保証するのは_排他的な所有権です。 –

1

unique_ptrは、コンパイラの観点から見た別のクラスです。それが現れると、そのポインタの1つが生ポインタを受け取ります。 dtorは生のポインタ(通常free)を渡してメモリを解放します。

可変部分が同じメモリ位置を指していても、unique_ptrの動作は変わりません。このコンテキストでは、これは別のローカルオブジェクトです。

unique_ptrで管理されている同じメモリへの未処理のポインタを保持していても(順序は関係ありません)、潜在的に2倍の空き領域と未定義の動作が発生する可能性があります(うまくいけばクラッシュ)。 new PartClassunique_ptr初期化に直接渡すことをおすすめします。

1

partunique_ptrに渡すと、unique_ptrへのポインタの所有権が渡されました。

はい、まだ未加工のポインタがありますが、スマートポインタに所有権を与えているので、あなたはそれを限界からはずすべきです。あなたは確かにそれを削除したくありません。

1

オブジェクトがまだ存在し、それが意図されたものなので、絶対に削除しないでください。質問は実際にはなぜpartがヌルポインタに設定されていないのですか?そのようなことを管理するのはあなた次第です。ポインタが有効なので、使用することができます。あなたがそれを使用したくない場合、それを守ってはいけません。

+0

ありがとうございますピート - あなたはそれを得た - 私の質問は本当に、なぜ一部はnullに設定されていませんでした – schulefant