Your SlideShare is downloading. ×
0
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

shared_ptr & weak_ptr (ppt 初版, DL 専用)

3,152

Published on

Web 上ではフォントが崩れます. (DL 専用) …

Web 上ではフォントが崩れます. (DL 専用)
Web 上で見る方は http://bit.ly/7dyNmz をどうぞ.
2009/12/12 Boost.勉強会プレゼン資料.
発表時のままの版.
プレゼン発表の録画は http://bit.ly/6yjSkz です.

Published in: Technology, Business
1 Comment
3 Likes
Statistics
Notes
  • hello
    My name is goodnews i saw your profile today and became interested in you,i will
    also like to know you the more,and i want you to send me your email address so
    that i can send you my photo for you to know whom i am.or you can contact me
    through my email address
    Here is my email address (goodnews.love1@yahoo.in)
    I believe we can move from here!
    I am waiting for your mail to my email address above.
    goodnews
    (Remember the distance or colour does not matter but love matters allot in life)
    please contact me here(goodnews.love1@yahoo.in
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
3,152
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
33
Comments
1
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. shared_ptr & weak_ptr くらいおらいと http://twitter.com/Cryolite/
  • 2. キーワードは 所有 ( ownership ) <ul><li>“…, so keeping track of an object’s ownership is hard work.” – More Effective C++ </li></ul><ul><li>“Observe the canonical exception-safety rules: Always use the “RAII” idiom to resource ownership and management.” – Exceptional C++ </li></ul><ul><li>“Containers of raw pointers make manual ownership management tricky, so …” – Modern C++ Design </li></ul>
  • 3. 所有とは… <ul><li>所有とは 権利 だ 俺が所有しているものを勝手に捨てるな </li></ul><ul><li>所有とは 義務 だ 1 回だけ,確実に,事後処理をしろ </li></ul>
  • 4. 所有を制するものが C++ を制する <ul><li>所有の権利を主張しないと… 「俺がまだ使っているのに捨てられた!」 </li></ul><ul><li>=> Dangling pointer </li></ul><ul><li>所有の義務を果たしていないと… 「誰も使ってないのに片付いていない!」 </li></ul><ul><li>=> Memory Leak </li></ul>
  • 5. 所有の種類と例 <ul><li>所有者がただ一人 , 所有者変更不可 </li></ul><ul><ul><li>配列とその要素 </li></ul></ul><ul><ul><li>クラスオブジェクトとメンバ変数 </li></ul></ul><ul><ul><li>関数スコープ ( の実行 ) と自動変数 </li></ul></ul><ul><ul><li>プログラム ( の実行 ) と静的変数 </li></ul></ul><ul><li>所有者がただ一人 , 所有者変更可 </li></ul><ul><ul><li>std::auto_ptr </li></ul></ul><ul><ul><li>( ムーブセマンティクス ) </li></ul></ul><ul><li>共有 – 所有者が複数 </li></ul><ul><ul><li>boost::shared_ptr </li></ul></ul>
  • 6. 共有は難しい
  • 7. 共有は難しい 私が片付けましょう
  • 8. 共有は難しい 私が片付けましょう いえいえ,ここは 私が片付けましょう
  • 9. 共有は難しい 私が片付けましょう いえいえ,ここは 私が片付けましょう え,ちょ,俺まだ使ってる
  • 10. shared_ptr – 共有を 所有カウント で簡単・安全に扱う 1 共有されるもの 所有カウント
  • 11. shared_ptr – 共有を 所有カウント で簡単・安全に扱う 2 共有されるもの 所有カウント
  • 12. shared_ptr – 共有を 所有カウント で簡単・安全に扱う 3 共有されるもの 所有カウント
  • 13. shared_ptr – 共有を 所有カウント で簡単・安全に扱う 4 共有されるもの 所有カウント
  • 14. shared_ptr – 共有を 所有カウント で簡単・安全に扱う 4 共有されるもの 所有カウント 所有カウントが 0 になったら 片づけを実行
  • 15. 所有カウントは所有の 権利を保障 する 1 共有されるもの 所有カウント 所有の権利: 誰かが所有していれば 勝手に片付けるな O.K.
  • 16. 所有カウントは所有の 義務を履行 する 0 共有されるもの 所有カウントが0になれば後片付け処理を実行 所有の義務: 1度だけ, 確実に, 片付け 所有カウント O.K.
  • 17. shared_ptr – 共有を 所有カウント で簡単・安全に扱う 4 共有されるもの 所有カウント
  • 18. shared_ptr – 共有を 所有カウント で簡単・安全に扱う 4 共有されるもの 所有カウント shared_ptr shared_ptr shared_ptr shared_ptr
  • 19. shared_ptr は所有 ( の義務と権利 ) とポインタだ <ul><li>ポインタとして動作する shared_ptr C++ の生ポインタと同じように動作 </li></ul><ul><li>所有の権利を保障する shared_ptr ポインタとして指しているものは生きている </li></ul><ul><li>所有の義務を履行する shared_ptr 所有カウントが 0 になったら関数オブジェクト ( デリータ ) を実行 </li></ul>強いポインタ 所有しているものとポインタが 指しているものを一致させる delete だけじゃない
  • 20. shared_ptr の基本 <ul><li>{ </li></ul><ul><li>shared_ptr<int> p(new int(42)); </li></ul><ul><li>cout << *p << endl; </li></ul><ul><li>shared_ptr<int> q = p; </li></ul><ul><li>p.reset(); </li></ul><ul><li>cout << *q << endl; </li></ul><ul><li>} </li></ul>
  • 21. shared_ptr の基本 <ul><li>{ </li></ul><ul><li>shared_ptr<int> p(new int(42)); </li></ul><ul><li>cout << *p << endl; </li></ul><ul><li>shared_ptr<int> q = p; </li></ul><ul><li>p.reset(); </li></ul><ul><li>cout << *q << endl; </li></ul><ul><li>} </li></ul>ポインタとして動作 + 権利を保障 ( 参照外しが安全 )
  • 22. shared_ptr の基本 <ul><li>{ </li></ul><ul><li>shared_ptr<int> p(new int(42)); </li></ul><ul><li>cout << *p << endl; </li></ul><ul><li>shared_ptr<int> q = p; </li></ul><ul><li>p.reset(); </li></ul><ul><li>cout << *q << endl; </li></ul><ul><li>} </li></ul>ポインタとして動作 + 権利を保障 ( 参照外しが安全 ) 義務を履行
  • 23. shared_ptr – int と同程度にスレッド安全 4 共有されるもの 所有カウント カウントの変化は 同期保護 shared_ptr shared_ptr shared_ptr shared_ptr
  • 24. 所有カウントは循環所有を扱えない 1 1 所有 所有 所有カウントが永遠に非 0
  • 25. 発表終わり
  • 26. shared_ptr の重要なデザインゴール <ul><li>ポインタと同等の型互換性 / バイナリ互換性 </li></ul><ul><li>非侵入性 – あなたのクラス定義に変更なし </li></ul>所有の共有・受け渡しを表現する 標準インタフェイスの確立
  • 27. オレオレスマートポインタ <ul><li>void processX(shared_ptr<X> px); </li></ul><ul><li>oreore_ptr<X> px(new X(…)); </li></ul><ul><li>processX(px); // コンパイルエラー </li></ul>
  • 28. オレオレスマートポインタ <ul><li>void processX(shared_ptr<X> px); </li></ul><ul><li>template<class P> struct D { </li></ul><ul><li>P p_; </li></ul><ul><li>void operator()(void const *) { p_.reset(); } </li></ul><ul><li>}; </li></ul><ul><li>oreore_ptr<X> px(new X(…)); </li></ul><ul><li>shared_ptr<X> qx(px.get(), D<oreore_ptr<X> >(px)); </li></ul><ul><li>processX(qx); </li></ul>
  • 29. オレオレスマートポインタ <ul><li>void processX(shared_ptr<X> px); </li></ul><ul><li>template<class P> struct D { </li></ul><ul><li>P p_; </li></ul><ul><li>void operator()(void const *) { p_.reset(); } </li></ul><ul><li>}; </li></ul><ul><li>oreore_ptr<X> px(new X(…)); </li></ul><ul><li>shared_ptr<X> qx(px.get(), D<oreore_ptr<X> >(px)); </li></ul><ul><li>processX(qx); </li></ul>「所有」は型に現れない = コンストラクタで「所有」が決まる shared_ptr の 「所有」は型に現れない ポイント 2 ポイント 1
  • 30. 所有しない <ul><li>void processX(shared_ptr<X> px); </li></ul><ul><li>static X x; // 静的変数 </li></ul><ul><li>struct NullDeleter { </li></ul><ul><li>void operator()(void *){} </li></ul><ul><li>}; </li></ul><ul><li>shared_ptr<X> px(&x, NullDeleter()); </li></ul><ul><li>processX(px); </li></ul>
  • 31. 所有しない <ul><li>void processX(shared_ptr<X> px); </li></ul><ul><li>static X x; // 静的変数 </li></ul><ul><li>Struct NullDeleter { </li></ul><ul><li>void operator()(void *){} </li></ul><ul><li>}; </li></ul><ul><li>shared_ptr<X> px(&x, NullDeleter()); </li></ul><ul><li>processX(px); </li></ul><ul><li>shared_ptr<X> px2(new X()); </li></ul><ul><li>processX(px2); </li></ul>「所有」は型に現れない = コンストラクタで「所有」が決まる shared_ptr の 「所有」は型に現れない ポイント 2 ポイント 1
  • 32. バイナリ境界を越える int main(){ int *p = new int(42); f(p); p = 0; ..... } void f(int *p){ ..... ..... delete p; } a.exe ( デバッグビルド ) b.dll ( リリースビルド ) 異なるコンパイル設定の new と delete の 組み合わせは環境によってはダウト
  • 33. バイナリ境界を越える int main(){ shared_ptr<int> p(new int(42)); f(p); p.reset(); ..... } void f(shared_ptr<int> p){ ..... ..... p.reset(); } a.exe ( デバッグビルド ) b.dll ( リリースビルド )
  • 34. バイナリ境界を越える int main(){ shared_ptr<int> p(new int(42)); f(p); p.reset(); ..... } void f(shared_ptr<int> p){ ..... ..... p.reset(); } a.exe ( デバッグビルド ) b.dll ( リリースビルド ) デバッグビルドの delete をここで設定
  • 35. バイナリ境界を越える int main(){ shared_ptr<int> p(new int(42)); f(p); p.reset(); ..... } void f(shared_ptr<int> p){ ..... ..... p.reset(); } a.exe ( デバッグビルド ) b.dll ( リリースビルド ) デバッグビルドの delete をここで設定 デバッグビルドの delete が呼び出される
  • 36. バイナリ境界を越える int main(){ shared_ptr<int> p(new int(42)); f(p); p.reset(); ..... } void f(shared_ptr<int> p){ ..... ..... p.reset(); } a.exe ( デバッグビルド ) b.dll ( リリースビルド ) デバッグビルドの delete が呼び出される デバッグビルドの delete をここで設定 どの delete が設定されていようが バイナリ互換性を維持
  • 37. 所有だけの shared_ptr shared_ptr<int> p(new int(42)); // (A) shared_ptr<void> q = p; p.reset(); // 以下, (A) で生成した int は q が所有
  • 38. shared_ptr<void> による遅延解放 <ul><li>// HeavyToDispose は削除のコスト大 </li></ul><ul><li>shared_ptr<HeavyToDispose> px(…); </li></ul><ul><li>… </li></ul><ul><li>// ここで削除して処理が止まると困る… </li></ul><ul><li>px.reset(); </li></ul>
  • 39. shared_ptr<void> による遅延解放 <ul><li>vector<shared_ptr<void> > to_be_disposed; </li></ul><ul><li>shared_ptr<HeavyToDispose1> px(…); </li></ul><ul><li>shared_ptr<HeavyToDispose2> py(…); </li></ul><ul><li>… </li></ul><ul><li>// ここで削除して処理が止まると困る… </li></ul><ul><li>to_be_disposed.push_back(px); px.reset(); </li></ul><ul><li>to_be_disposed.push_back(py); py.reset(); </li></ul><ul><li>… </li></ul><ul><li>// 適当なタイミング or 別スレッドで </li></ul><ul><li>// to_be_disposed.clear() を実行 </li></ul>
  • 40. weak_ptr 4, 2 共有されるもの 所有カウント shared_ptr shared_ptr shared_ptr shared_ptr weak_ptr weak_ptr 弱いカウント
  • 41. weak_ptr 0, 2 共有されるもの 所有カウント shared_ptr shared_ptr shared_ptr shared_ptr weak_ptr weak_ptr 弱いカウント
  • 42. weak_ptr 0, 2 共有されるもの 所有カウント weak_ptr weak_ptr 弱いカウント 所有カウントが 0 になったら 片づけを実行
  • 43. weak_ptr 0, 2 所有カウント weak_ptr weak_ptr 弱いカウント
  • 44. weak_ptr 0, 0 所有カウント weak_ptr weak_ptr 弱いカウント
  • 45. weak_ptr 0, 0 weak_ptr weak_ptr 弱いカウントが 0 になったら カウントオブジェクトを片付け
  • 46. weak_ptr にできること – その 1 4, 2 共有されるもの 所有カウント shared_ptr shared_ptr shared_ptr shared_ptr weak_ptr weak_ptr 弱いカウント 「所有カウントが 0 かどうか?」に答える weak_ptr::expired == false
  • 47. weak_ptr にできること – その 1 0, 2 所有カウント weak_ptr weak_ptr 弱いカウント 「所有カウントが 0 かどうか?」に答える weak_ptr::expired == true
  • 48. weak_ptr にできること – その 1 0, 2 所有カウント weak_ptr weak_ptr 弱いカウント 「所有カウントが 0 かどうか?」に答える = 「対象が死んでいるかどうか?」に答える
  • 49. weak_ptr にできること – その 2 1, 2 共有されるもの 所有カウント shared_ptr weak_ptr weak_ptr 弱いカウント 対象が生きていたら,それを 所有する shared_ptr を作り出せる
  • 50. weak_ptr にできること – その 2 2, 2 共有されるもの 所有カウント shared_ptr weak_ptr weak_ptr 弱いカウント shared_ptr 対象が生きていたら,それを 所有する shared_ptr を作り出せる
  • 51. weak_ptr にできること – その 2 0, 2 所有カウント weak_ptr weak_ptr 弱いカウント 対象が死んでいたら空の shared_ptr しか取り出せない
  • 52. weak_ptr にできること – その 2 0, 2 所有カウント weak_ptr weak_ptr 弱いカウント shared_ptr 対象が死んでいたら空の shared_ptr しか取り出せない
  • 53. weak_ptr にできることのまとめ <ul><li>「対象が生きているかどうか?」を答える プロクシ </li></ul><ul><li>対象が生きていたら shared_ptr に 格上げ可能 </li></ul>
  • 54. weak_ptr の基本 <ul><li>shared_ptr<int> p(new int(42)); // (A) </li></ul><ul><li>weak_ptr<int> wp = p; </li></ul><ul><li>cout << wp.expired() << endl; // => “false” </li></ul><ul><li>shared_ptr<int> q = wp.lock(); </li></ul><ul><li>cout << *q << endl; // => “42”, q も所有 </li></ul><ul><li>p.reset(); q.reset(); // (A) の int を解放 </li></ul><ul><li>cout << wp.expired() << endl; // => “true” </li></ul><ul><li>shared_ptr<int> r = wp.lock(); </li></ul><ul><li>assert(r == 0); </li></ul>
  • 55. 生ポインタから shared_ptr を取得したい <ul><li>void Framework::onEvent(X *p) </li></ul><ul><li>{ </li></ul><ul><li>// *p を所有する shared_ptr を取りたい </li></ul><ul><li>} </li></ul>
  • 56. this への shared_ptr <ul><li>struct X { </li></ul><ul><li>shared_ptr<X> this_; // this への shared_ptr </li></ul><ul><li>shared_ptr<X> getShared(){ return this_; } </li></ul><ul><li>}; </li></ul><ul><li>void Framework::onEvent(X *p) </li></ul><ul><li>{ </li></ul><ul><li>shared_ptr<X> px = p->getShared(); </li></ul><ul><li>} </li></ul>
  • 57. this への shared_ptr はダメ <ul><li>struct X { </li></ul><ul><li>shared_ptr<X> this_; // this への shared_ptr </li></ul><ul><li>shared_ptr<X> getShared(){ return this_; } </li></ul><ul><li>}; </li></ul><ul><li>void Framework::onEvent(X *p) </li></ul><ul><li>{ </li></ul><ul><li>shared_ptr<X> px = p->getShared(); </li></ul><ul><li>} </li></ul>
  • 58. this への shared_ptr はダメ <ul><li>struct X { </li></ul><ul><li>shared_ptr<X> this_; // this への shared_ptr </li></ul><ul><li>shared_ptr<X> getShared(){ return this_; } </li></ul><ul><li>}; </li></ul><ul><li>void Framework::onEvent(X *p) </li></ul><ul><li>{ </li></ul><ul><li>shared_ptr<X> px = p->getShared(); </li></ul><ul><li>} </li></ul>X X::shared_ptr this_ クラスオブジェクトは メンバ変数を所有 所有 Q. なぜダメか? A. 所有が循環しているのでダメ
  • 59. weak_ptr の使い方 – this への weak_ptr <ul><li>struct X { </li></ul><ul><li>weak_ptr<X> this_; // this への weak_ptr </li></ul><ul><li>shared_ptr<X> getShared(){ return this_; } </li></ul><ul><li>}; </li></ul><ul><li>void Framework::onEvent(X *p) </li></ul><ul><li>{ </li></ul><ul><li>shared_ptr<X> px = p->getShared(); </li></ul><ul><li>} </li></ul>
  • 60. weak_ptr の使い方 – this への weak_ptr <ul><li>struct X { </li></ul><ul><li>weak_ptr<X> this_; // this への weak_ptr </li></ul><ul><li>shared_ptr<X> getShared(){ return this_; } </li></ul><ul><li>}; </li></ul><ul><li>void Framework::onEvent(X *p) </li></ul><ul><li>{ </li></ul><ul><li>shared_ptr<X> px = p->getShared(); </li></ul><ul><li>} </li></ul>参考: boost::enable_shared_from_this
  • 61. Observer (Publisher/Subscriber)
  • 62. Observer でよくある事故
  • 63. Observer でよくある事故 死んだオブジェクトにアクセス
  • 64. 安全な Observer <ul><li>死んだオブジェクトにイベントを通知しない </li></ul><ul><li>イベント通知中に subscriber を解放させない </li></ul>
  • 65. 安全な Observer void Publisher::subscribe(function<void ()> call_back, weak_ptr<void> wp); shared_ptr<Subscriber1> p… Publisher::subscribe( bind(&Subscriber1::notifyEvent, p.get()), p);
  • 66. 安全な Observer weak_ptr<void> wp…; // subscriber への weak_ptr if (shared_ptr<void> p = wp.lock()) { call_back(); }
  • 67. 安全な Observer … ということが Boost.Signal2 で出来ます 鍵は weak_ptr<void> & shared_ptr<void>
  • 68. オブジェクト間グローバルマッピング a b c share_ptr share_ptr share_ptr share_ptr
  • 69. オブジェクト間グローバルマッピング a b c map<void *, Y> g_map; // グローバル y1 y2 y3 share_ptr share_ptr share_ptr share_ptr
  • 70. オブジェクト間グローバルマッピング a b c y1 y2 y3 share_ptr share_ptr share_ptr share_ptr c が消えると… map<void *, Y> g_map; // グローバル
  • 71. オブジェクト間グローバルマッピング a b c y1 y2 y3 share_ptr share_ptr share_ptr share_ptr c が消えると… 無駄なマップエントリ ( デッドマップ ) が発生 map<void *, Y> g_map; // グローバル
  • 72. 策 1. キーを weak_ptr にして適度にクリーンアップ a b c map< weak_ptr<void> , Y> g_map; y1 y2 y3 share_ptr share_ptr
  • 73. 策 1. キーを weak_ptr にして適度にクリーンアップ a b c map< weak_ptr<void> , Y> g_map; y1 y2 y3 share_ptr share_ptr // 以下を適度に実行 for ( auto i = g_map.begin(); i != g_map.end();) { if (i->first.expired()) g_map.erase(i++); else ++i; }
  • 74. 策 1. キーを weak_ptr にして適度にクリーンアップ a b c map< weak_ptr<void> , Y> g_map; y1 y2 y3 share_ptr share_ptr デッドマップが適度に解消される
  • 75. 策2. マップエントリも所有する a b c y1 y2 y3 share_ptr share_ptr share_ptr share_ptr map<void *, Y>
  • 76. 策2. マップエントリも所有する a b c y1 y2 y3 share_ptr share_ptr share_ptr share_ptr map<void *, Y> struct D{ map<void *, Y> &m_; void operator()(void *p){ m_.erase(p); delete p; } }; D d(g_map); shared_ptr<C> pc(new C(), D(g_map)); g_map.insert(make_pair(pc.get(), Y(…)));
  • 77. 策2. マップエントリも所有する a b c map<void *, Y> y1 y2 y3 share_ptr share_ptr share_ptr share_ptr c を所有する shared_ptr がなくなると…
  • 78. 策2. マップエントリも所有する a b c unordered_map<void const *, Y> y1 y2 y3 share_ptr share_ptr share_ptr share_ptr c を所有する shared_ptr がなくなると… c をキーとするエントリも自動で erase
  • 79. 循環所有を何とかする <ul><li>// こういうことがしたい </li></ul><ul><li>shared_ptr<X> px = …; </li></ul><ul><li>shared_ptr<Y> py = …; </li></ul><ul><li>pyy = px->getSharedY(); // X が Y を所有? </li></ul><ul><li>assert(pyy == py); </li></ul><ul><li>pxx = py->getSharedX(); // Y が X を所有? </li></ul><ul><li>assert(pxx == px); </li></ul>
  • 80. 循環所有を何とかする <ul><li>// こういうことがしたい </li></ul><ul><li>shared_ptr<X> px = …; </li></ul><ul><li>shared_ptr<Y> py = …; </li></ul><ul><li>pyy = px->getSharedY(); // X が Y を所有? </li></ul><ul><li>assert(pyy == py); </li></ul><ul><li>pxx = py->getSharedX(); // Y が X を所有? </li></ul><ul><li>assert(pxx == px); </li></ul>X Y 所有 所有 ?
  • 81. 循環所有を何とかする <ul><li>// こういうことがしたい </li></ul><ul><li>shared_ptr<X> px = …; </li></ul><ul><li>shared_ptr<Y> py = …; </li></ul><ul><li>pyy = px->getSharedY(); // X が Y を所有? </li></ul><ul><li>assert(pyy == py); </li></ul><ul><li>pxx = py->getSharedX(); // Y が X を所有? </li></ul><ul><li>assert(pxx == px); </li></ul>X Y shared_ptr 所有 所有
  • 82. 循環所有を何とかする <ul><li>// こういうことがしたい </li></ul><ul><li>shared_ptr<X> px = …; </li></ul><ul><li>shared_ptr<Y> py = …; </li></ul><ul><li>pyy = px->getSharedY(); // X が Y を所有? </li></ul><ul><li>assert(pyy == py); </li></ul><ul><li>pxx = py->getSharedX(); // Y が X を所有? </li></ul><ul><li>assert(pxx == px); </li></ul>X Y shared_ptr 所有 所有 ポイント shared_ptr<X>
  • 83. 循環所有を何とかする <ul><li>// こういうことがしたい </li></ul><ul><li>shared_ptr<X> px = …; </li></ul><ul><li>shared_ptr<Y> py = …; </li></ul><ul><li>pyy = px->getSharedY(); // X が Y を所有? </li></ul><ul><li>assert(pyy == py); </li></ul><ul><li>pxx = py->getSharedX(); // Y が X を所有? </li></ul><ul><li>assert(pxx == px); </li></ul>X Y shared_ptr 所有 所有 shared_ptr<Y> ポイント
  • 84. 循環所有を何とかする <ul><li>// こういうことがしたい </li></ul><ul><li>shared_ptr<X> px = …; </li></ul><ul><li>shared_ptr<Y> py = …; </li></ul><ul><li>pyy = px->getSharedY(); // X が Y を所有? </li></ul><ul><li>assert(pyy == py); </li></ul><ul><li>pxx = py->getSharedX(); // Y が X を所有? </li></ul><ul><li>assert(pxx == px); </li></ul>X Y shared_ptr 所有 所有 shared_ptr<Y> ポイント
  • 85. まとめ <ul><li>C++ では所有が重要 </li></ul><ul><li>shared_ptr は所有者が複数居る場合に </li></ul><ul><ul><li>所有カウントで簡単・安全に動作 </li></ul></ul><ul><ul><li>動的デリータによる高い互換性を維持 </li></ul></ul><ul><li>weak_ptr </li></ul><ul><ul><li>「生きているかどうか」を答えるプロキシ </li></ul></ul><ul><ul><li>shared_ptr に格上げして一時的に所有 </li></ul></ul><ul><li>shared_ptr / weak_ptr で楽しい C++ ライフ </li></ul>

×