shared_ptr
は強い/弱い参照回数をともに保持する。値渡しが行われると
shared_ptr
のcopy contructorが呼ばれる。それに伴い、強い参照回数がincrementされる。引数が一時オブジェクトであれば、 move constructorが呼ばれるので、参照回数は更新されない。しかし、一時オブジェクトが渡されることは稀である。- 関数
f
から抜ける際、shared_ptr
のdestructorが呼ばれる。このとき参照回数が減らされる。
- 参照回数はatomicな共有変数である。したがって、increment/decrementを行うと、共有メモリからの読み出しとそれへの書き込みが同期的に実行される。incrementのばあい適切な最適化が行われるのでそのコストは大きくない。しかし、decrementのときは、処理が複雑なため最適化に制限がかかる。
- 同期処理が行われるため、スレッドの数とパフォーマンスの良さが比例しない(scalabilityが失われる)。
こう書いたとき、関数
f
の引数の寿命について責任を持つのは、呼び出し側である。
すなわち、f
は呼び出し側の引数管理の影響を受ける。read-onlyならこう書く。
この場合、引数の所有権は関数
f
に移り、f
のスコープを抜けると同時にそのオブジェクトは破棄される。見方を変えれば、オブジェクトを"吸い込む"関数が必要なら、unique_ptr
の値渡しで引数を表現すればよい。上記のconst
版は意図が不明瞭である。
前者が意図していることは、関数内部で
unique_ptr
自身が更新されることである。
一方、後者は意図が不明瞭である。
呼び出し側と呼び出された側で所有権を共有したい場合にこれを使う。
shared_ptr
自身を更新したい場合これを使う。
shared_ptr
自身を更新する必要があるのかないのか定かでない場合これを使う。
参照
0 件のコメント:
コメントを投稿