2017-11-15 13 views
-4

まず、std::weak_ptrの典型的な実装は何ですか?特にstd::weak_ptrは、std::shared_ptrの制御ブロックへのポインタにすぎませんか?memcpy std :: weak_ptr?

std::shared_ptrの参照がすべて消えた場合、内部コントロールブロックは削除されますか?もしそうなら、std::weak_ptr::expired()は、そのメモリが再利用されていると、どのように正しく機能しますか?


私はstd::weak_ptrを含むオブジェクトを持っている、と私は後で処理するためのバッファにオブジェクトをmemcpyたい。スマートポインタの内部動作を何らかの方法で破るつもりですか?

+2

http://en.cppreference.com/w/cpp/types/is_trivially_copyable#Notes。 ['std :: weak_ptr'](http://en.cppreference.com/w/cpp/memory/weak_ptr/weak_ptr)は、正しく読めば、重大なコンストラクタを持っています。 – Justin

+1

@Justin非自明なコンストラクタの存在は問題ではなく、ほんの些細なコピーまたは移動コンストラクタの存在のみです。ただし、 'weak_ptr'をコピーするとコントロールブロックを変更する必要があるため、実装では簡単な' std :: weak_ptr'コピーコンストラクタを使用することは不可能です。 –

+0

"_particularly std :: weak_ptr std :: shared_ptr_の制御ブロックへのポインタ"ではなく "**"が含まれています** – curiousguy

答えて

5

すべてがstd::shared_ptrのオブジェクトがなくなっても、コントロールブロックはまだ存在しています(つまり、std::weak_ptrの動作)、参照されているオブジェクトのみが削除されます。

ここで、C++オブジェクトはstd::memcpyonly if it is trivially copyableで安全にコピーできます。 TriviallyCopyableのコンセプトの要件を確認すると、わかりやすいコピーコンストラクタがあるため、std::weak_ptrはそれを満たしていないことがわかります。実際には、このコンストラクタはコントロールブロック内の弱ポインタ​​カウンタを増加させるので、std::memcpyでそれをコピーするとその不変量が壊れます。

生のバッファにstd::weak_ptrを格納するのは、通常のコードではひどい考え方です。バッファは、通常、シリアル化、データの送信/書き込みなどに使用され、これらのタスクはスマートポインタにとっては無意味です。しかし、あなたはバッファに保管する必要があることが確実な場合は、placement newを必要とする:

std::weak_ptr<T> the_one_i_want_to_copy; 

std::weak_ptr<T> * buffer = ...; 
new (buffer) std::weak_ptr<T> { the_one_i_want_to_copy }; 

お知らせ(buffer)new後:それはメモリを割り当てるために、すでに準備を使用しないようnewを伝えます場所(したがって場所新規)。 bufferを準備するときは、必要なサイズと位置合わせをしてください。

+0

その他の用途は、 'optional'や' variant '。しかし、それは少なくとも少し奇妙です。しかし、本当に 'weak_ptr'をバッファにコピーする必要がある場合、正しいツールは新しい配置です。 –

+0

@DanielH非常に良い点です!私はこれを答えに加えます、ありがとう。 – lisyarus

関連する問題