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

85
06/16/22 1 shared_ptr & weak_p tr くくくくくくく http://twitter.com/Cryolite/

Upload: cryolite

Post on 31-May-2015

3.137 views

Category:

Technology


2 download

DESCRIPTION

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

TRANSCRIPT

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

04/12/231

shared_ptr & weak_ptrくらいおらいと

http://twitter.com/Cryolite/

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

04/12/232

キーワードは所有 (ownership)

• “…, so keeping track of an object’s ownership is hard work.” – More Effective C++

• “Observe the canonical exception-safety rules: Always use the “RAII” idiom to resource ownership and management.” – Exceptional C++

• “Containers of raw pointers make manual ownership management tricky, so …” – Modern C++ Design

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

04/12/233

所有とは…

• 所有とは権利だ俺が所有しているものを勝手に捨てるな

• 所有とは義務だ1 回だけ,確実に,事後処理をしろ

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

04/12/234

所有を制するものが C++ を制する

• 所有の権利を主張しないと…「俺がまだ使っているのに捨てられた!」

=> Dangling pointer

• 所有の義務を果たしていないと…「誰も使ってないのに片付いていない!」

=> Memory Leak

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

04/12/235

所有の種類と例• 所有者がただ一人 , 所有者変更不可• 配列とその要素• クラスオブジェクトとメンバ変数• 関数スコープ ( の実行 ) と自動変数• プログラム ( の実行 ) と静的変数

• 所有者がただ一人 , 所有者変更可• std::auto_ptr• ( ムーブセマンティクス )

• 共有 – 所有者が複数• boost::shared_ptr

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

04/12/236

共有は難しい

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

04/12/237

共有は難しい

私が片付けましょう

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

04/12/238

共有は難しい

私が片付けましょういえいえ,ここは

私が片付けましょう

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

04/12/239

共有は難しい

私が片付けましょういえいえ,ここは

私が片付けましょう

え,ちょ,俺まだ使ってる

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

04/12/2310

shared_ptr – 共有を所有カウントで簡単・安全に扱う

1

共有されるもの

所有カウント

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

04/12/2311

shared_ptr – 共有を所有カウントで簡単・安全に扱う

2

共有されるもの

所有カウント

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

04/12/2312

shared_ptr – 共有を所有カウントで簡単・安全に扱う

3

共有されるもの

所有カウント

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

04/12/2313

shared_ptr – 共有を所有カウントで簡単・安全に扱う

4

共有されるもの

所有カウント

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

04/12/2314

shared_ptr – 共有を所有カウントで簡単・安全に扱う

4

共有されるもの

所有カウント所有カウントが 0 になったら片づけを実行

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

04/12/2315

所有カウントは所有の権利を保障する

1

共有されるもの

所有カウント

所有の権利:誰かが所有していれば勝手に片付けるな

O.K.

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

04/12/2316

所有カウントは所有の義務を履行する

0

共有されるもの

所有カウントが 0 になれば後片付け処理を実行

所有の義務:1 度だけ , 確実に , 片付け

所有カウント

O.K.

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

04/12/2317

shared_ptr – 共有を所有カウントで簡単・安全に扱う

4

共有されるもの

所有カウント

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

04/12/2318

shared_ptr – 共有を所有カウントで簡単・安全に扱う

4

共有されるもの

所有カウント

shared_ptr shared_ptr shared_ptr shared_ptr

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

04/12/2319

shared_ptr は所有 ( の義務と権利 ) とポインタだ

• ポインタとして動作する shared_ptrC++ の生ポインタと同じように動作

• 所有の権利を保障する shared_ptrポインタとして指しているものは生きている

• 所有の義務を履行する shared_ptr所有カウントが 0 になったら関数オブジェクト ( デリータ ) を実行

強いポインタ所有しているものとポインタが

指しているものを一致させる

delete だけじゃない

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

04/12/2320

shared_ptr の基本

{ shared_ptr<int> p(new int(42)); cout << *p << endl; shared_ptr<int> q = p; p.reset(); cout << *q << endl;}

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

04/12/2321

shared_ptr の基本

{ shared_ptr<int> p(new int(42)); cout << *p << endl; shared_ptr<int> q = p; p.reset(); cout << *q << endl;} ポインタとして動作

+権利を保障 ( 参照外しが安全 )

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

04/12/2322

shared_ptr の基本

{ shared_ptr<int> p(new int(42)); cout << *p << endl; shared_ptr<int> q = p; p.reset(); cout << *q << endl;} ポインタとして動作

+権利を保障 ( 参照外しが安全 )

義務を履行

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

04/12/2323

shared_ptr – int と同程度にスレッド安全

4

共有されるもの

所有カウントカウントの変化は同期保護

shared_ptr shared_ptr shared_ptr shared_ptr

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

04/12/2324

所有カウントは循環所有を扱えない

所有

所有

所有カウントが永遠に非 0

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

04/12/2325

発表終わり

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

04/12/2326

shared_ptr の重要なデザインゴール

• ポインタと同等の型互換性 / バイナリ互換性

• 非侵入性 – あなたのクラス定義に変更なし

所有の共有・受け渡しを表現する

標準インタフェイスの確立

所有の共有・受け渡しを表現する

標準インタフェイスの確立

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

04/12/2327

オレオレスマートポインタvoid processX(shared_ptr<X> px);

oreore_ptr<X> px(new X(…));processX(px); // コンパイルエラー

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

04/12/2328

オレオレスマートポインタvoid processX(shared_ptr<X> px);

template<class P> struct D { P p_; void operator()(void const *) { p_.reset(); }};

oreore_ptr<X> px(new X(…));shared_ptr<X> qx(px.get(), D<oreore_ptr<X> >(p

x));processX(qx);

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

04/12/2329

オレオレスマートポインタvoid processX(shared_ptr<X> px);

template<class P> struct D { P p_; void operator()(void const *) { p_.reset(); }};

oreore_ptr<X> px(new X(…));shared_ptr<X> qx(px.get(), D<oreore_ptr<X> >(p

x));processX(qx);

「所有」は型に現れない=

コンストラクタで「所有」が決まる

shared_ptr の「所有」は型に現れない

ポイント 2

ポイント 1

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

04/12/2330

所有しないvoid processX(shared_ptr<X> px);

static X x; // 静的変数

struct NullDeleter { void operator()(void *){}};

shared_ptr<X> px(&x, NullDeleter());processX(px);

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

04/12/2331

所有しないvoid processX(shared_ptr<X> px);

static X x; // 静的変数

Struct NullDeleter { void operator()(void *){}};

shared_ptr<X> px(&x, NullDeleter());processX(px);shared_ptr<X> px2(new X());processX(px2);

「所有」は型に現れない=

コンストラクタで「所有」が決まる

shared_ptr の「所有」は型に現れない

ポイント 2

ポイント 1

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

04/12/2332

バイナリ境界を越える

int main(){ int *p = new int(42); f(p); p = 0; .....}

void f(int *p){ ..... ..... delete p;}

a.exe ( デバッグビルド ) b.dll ( リリースビルド )

異なるコンパイル設定の new と delete の組み合わせは環境によってはダウト

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

04/12/2333

バイナリ境界を越える

int main(){ shared_ptr<int> p(new int(4

2)); f(p); p.reset(); .....}

void f(shared_ptr<int> p){ ..... ..... p.reset();}

a.exe ( デバッグビルド ) b.dll ( リリースビルド )

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

04/12/2334

バイナリ境界を越える

int main(){ shared_ptr<int> p(new int(4

2)); f(p); p.reset(); .....}

void f(shared_ptr<int> p){ ..... ..... p.reset();}

a.exe ( デバッグビルド ) b.dll ( リリースビルド )

デバッグビルドの delete をここで設定

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

04/12/2335

バイナリ境界を越える

int main(){ shared_ptr<int> p(new int(4

2)); f(p); p.reset(); .....}

void f(shared_ptr<int> p){ ..... ..... p.reset();}

a.exe ( デバッグビルド ) b.dll ( リリースビルド )

デバッグビルドの delete をここで設定デバッグビルドの delete が呼び出され

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

04/12/2336

バイナリ境界を越える

int main(){ shared_ptr<int> p(new int(4

2)); f(p); p.reset(); .....}

void f(shared_ptr<int> p){ ..... ..... p.reset();}

a.exe ( デバッグビルド ) b.dll ( リリースビルド )

デバッグビルドの delete が呼び出される

デバッグビルドの delete をここで設定

どの delete が設定されていようがバイナリ互換性を維持

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

04/12/2337

所有だけの shared_ptr

shared_ptr<int> p(new int(42)); // (A)

shared_ptr<void> q = p;p.reset();// 以下, (A) で生成した int は q が所有

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

04/12/2338

shared_ptr<void> による遅延解放

// HeavyToDispose は削除のコスト大shared_ptr<HeavyToDispose> px(…);…// ここで削除して処理が止まると困る…px.reset();

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

04/12/2339

shared_ptr<void> による遅延解放vector<shared_ptr<void> > to_be_disposed;

shared_ptr<HeavyToDispose1> px(…);shared_ptr<HeavyToDispose2> py(…);…// ここで削除して処理が止まると困る…to_be_disposed.push_back(px); px.reset();to_be_disposed.push_back(py); py.reset();…// 適当なタイミング or 別スレッドで// to_be_disposed.clear() を実行

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

04/12/2340

weak_ptr

4, 2

共有されるもの

所有カウント

shared_ptr shared_ptr

shared_ptr shared_ptrweak_ptr

weak_ptr

弱いカウント

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

04/12/2341

weak_ptr

0, 2

共有されるもの

所有カウント

shared_ptr shared_ptr

shared_ptr shared_ptrweak_ptr

weak_ptr

弱いカウント

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

04/12/2342

weak_ptr

0, 2

共有されるもの

所有カウント

weak_ptr

weak_ptr

弱いカウント

所有カウントが 0 になったら片づけを実行

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

04/12/2343

weak_ptr

0, 2所有カウント

weak_ptr

weak_ptr

弱いカウント

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

04/12/2344

weak_ptr

0, 0所有カウント

weak_ptr

weak_ptr

弱いカウント

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

04/12/2345

weak_ptr

0, 0

weak_ptr

weak_ptr

弱いカウントが 0 になったらカウントオブジェクトを片付け

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

04/12/2346

weak_ptr にできること – その 1

4, 2

共有されるもの

所有カウント

shared_ptr shared_ptr

shared_ptr shared_ptrweak_ptr

weak_ptr

弱いカウント

「所有カウントが 0 かどうか?」に答える

weak_ptr::expired == false

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

04/12/2347

weak_ptr にできること – その 1

0, 2所有カウント

weak_ptr

weak_ptr

弱いカウント

「所有カウントが 0 かどうか?」に答える

weak_ptr::expired == true

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

04/12/2348

weak_ptr にできること – その 1

0, 2所有カウント

weak_ptr

weak_ptr

弱いカウント

「所有カウントが 0 かどうか?」に答える=

「対象が死んでいるかどうか?」に答える

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

04/12/2349

weak_ptr にできること – その 2

1, 2

共有されるもの

所有カウント

shared_ptr

weak_ptrweak_ptr

弱いカウント

対象が生きていたら,それを所有する shared_ptr を作り出せる

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

04/12/2350

weak_ptr にできること – その 2

2, 2

共有されるもの

所有カウント

shared_ptr

weak_ptrweak_ptr

弱いカウント

shared_ptr

対象が生きていたら,それを所有する shared_ptr を作り出せる

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

04/12/2351

weak_ptr にできること – その 2

0, 2所有カウント

weak_ptrweak_ptr

弱いカウント

対象が死んでいたら空の shared_ptr しか取り出せない

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

04/12/2352

weak_ptr にできること – その 2

0, 2所有カウント

weak_ptrweak_ptr

弱いカウント

shared_ptr

対象が死んでいたら空の shared_ptr しか取り出せない

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

04/12/2353

weak_ptr にできることのまとめ

• 「対象が生きているかどうか?」を答えるプロクシ

• 対象が生きていたら shared_ptr に格上げ可能

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

04/12/2354

weak_ptr の基本shared_ptr<int> p(new int(42)); // (A)weak_ptr<int> wp = p;cout << wp.expired() << endl; // => “false”shared_ptr<int> q = wp.lock();cout << *q << endl; // => “42”, q も所有p.reset(); q.reset(); // (A) の int を解放cout << wp.expired() << endl; // => “true”shared_ptr<int> r = wp.lock();assert(r == 0);

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

04/12/2355

生ポインタから shared_ptr を取得したい

void Framework::onEvent(X *p){ // *p を所有する shared_ptr を取りたい}

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

04/12/2356

this への shared_ptrstruct X { shared_ptr<X> this_; // this への shared_

ptr shared_ptr<X> getShared(){ return this_; }};

void Framework::onEvent(X *p){ shared_ptr<X> px = p->getShared();}

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

04/12/2357

this への shared_ptr はダメstruct X { shared_ptr<X> this_; // this への shared_

ptr shared_ptr<X> getShared(){ return this_; }};

void Framework::onEvent(X *p){ shared_ptr<X> px = p->getShared();}

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

04/12/2358

this への shared_ptr はダメstruct X { shared_ptr<X> this_; // this への shared_

ptr shared_ptr<X> getShared(){ return this_; }};

void Framework::onEvent(X *p){ shared_ptr<X> px = p->getShared();}

X

X::shared_ptr this_

クラスオブジェクトはメンバ変数を所有 所有

Q. なぜダメか?

A. 所有が循環しているのでダメ

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

04/12/2359

weak_ptr の使い方 – this への weak_ptrstruct X { weak_ptr<X> this_; // this への weak_ptr shared_ptr<X> getShared(){ return this_; }};

void Framework::onEvent(X *p){ shared_ptr<X> px = p->getShared();}

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

04/12/2360

weak_ptr の使い方 – this への weak_ptrstruct X { weak_ptr<X> this_; // this への weak_ptr shared_ptr<X> getShared(){ return this_; }};

void Framework::onEvent(X *p){ shared_ptr<X> px = p->getShared();}

参考: boost::enable_shared_from_this

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

04/12/2361

Observer (Publisher/Subscriber)

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

04/12/2362

Observer でよくある事故

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

04/12/2363

Observer でよくある事故

死んだオブジェクトにアクセス

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

04/12/2364

安全な Observer

• 死んだオブジェクトにイベントを通知しない• イベント通知中に subscriber を解放させない

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

04/12/2365

安全な Observer

void Publisher::subscribe(function<void ()> call_back, weak_ptr<void> wp);

shared_ptr<Subscriber1> p…Publisher::subscribe( bind(&Subscriber1::notifyEvent, p.get()), p);

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

04/12/2366

安全な Observer

weak_ptr<void> wp…; // subscriber への weak_ptrif (shared_ptr<void> p = wp.lock()) { call_back();}

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

04/12/2367

安全な Observer

… ということが Boost.Signal2 で出来ます鍵は weak_ptr<void> & shared_ptr<void>

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

04/12/2368

オブジェクト間グローバルマッピング

a

b

c

share_ptr

share_ptr

share_ptr share_ptr

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

04/12/2369

オブジェクト間グローバルマッピング

a

b

c

map<void *, Y> g_map; // グローバル

y1

y2

y3

share_ptr

share_ptr

share_ptr share_ptr

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

04/12/2370

オブジェクト間グローバルマッピング

a

b

c

y1

y2

y3

share_ptr

share_ptr share_ptr

share_ptr

c が消えると…

map<void *, Y> g_map; // グローバル

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

04/12/2371

オブジェクト間グローバルマッピング

a

b

c

y1

y2

y3

share_ptr

share_ptr share_ptr

share_ptr

c が消えると… 無駄なマップエントリ( デッドマップ ) が発生

map<void *, Y> g_map; // グローバル

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

04/12/2372

策 1. キーを weak_ptr にして適度にクリーンアップ

a

b

c

map<weak_ptr<void>, Y> g_map;

y1

y2

y3

share_ptr

share_ptr

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

04/12/2373

策 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.en

d();) { if (i->first.expired()) g_map.erase(i++); else ++i;}

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

04/12/2374

策 1. キーを weak_ptr にして適度にクリーンアップ

a

b

c

map<weak_ptr<void>, Y> g_map;

y1

y2

y3

share_ptr

share_ptr

デッドマップが適度に解消される

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

04/12/2375

策 2. マップエントリも所有する

a

b

c

y1

y2

y3

share_ptr

share_ptr

share_ptr share_ptr

map<void *, Y>

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

04/12/2376

策 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(…)));

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

04/12/2377

策 2. マップエントリも所有する

a

b

c

map<void *, Y>

y1

y2

y3

share_ptr

share_ptr

share_ptr share_ptr

c を所有する shared_ptr がなくなると…

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

04/12/2378

策 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

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

04/12/2379

循環所有を何とかする// こういうことがしたいshared_ptr<X> px = …;shared_ptr<Y> py = …;

pyy = px->getSharedY(); // X が Y を所有?assert(pyy == py);

pxx = py->getSharedX(); // Y が X を所有?assert(pxx == px);

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

04/12/2380

循環所有を何とかする// こういうことがしたいshared_ptr<X> px = …;shared_ptr<Y> py = …;

pyy = px->getSharedY(); // X が Y を所有?assert(pyy == py);

pxx = py->getSharedX(); // Y が X を所有?assert(pxx == px);

X Y

所有

所有

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

04/12/2381

循環所有を何とかする// こういうことがしたいshared_ptr<X> px = …;shared_ptr<Y> py = …;

pyy = px->getSharedY(); // X が Y を所有?assert(pyy == py);

pxx = py->getSharedX(); // Y が X を所有?assert(pxx == px);

X Y

shared_ptr

所有 所有

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

04/12/2382

循環所有を何とかする// こういうことがしたいshared_ptr<X> px = …;shared_ptr<Y> py = …;

pyy = px->getSharedY(); // X が Y を所有?assert(pyy == py);

pxx = py->getSharedX(); // Y が X を所有?assert(pxx == px);

X Y

shared_ptr

所有 所有ポイント

shared_ptr<X>

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

04/12/2383

循環所有を何とかする// こういうことがしたいshared_ptr<X> px = …;shared_ptr<Y> py = …;

pyy = px->getSharedY(); // X が Y を所有?assert(pyy == py);

pxx = py->getSharedX(); // Y が X を所有?assert(pxx == px);

X Y

shared_ptr

所有 所有

shared_ptr<Y>

ポイント

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

04/12/2384

循環所有を何とかする// こういうことがしたいshared_ptr<X> px = …;shared_ptr<Y> py = …;

pyy = px->getSharedY(); // X が Y を所有?assert(pyy == py);

pxx = py->getSharedX(); // Y が X を所有?assert(pxx == px);

X Y

shared_ptr

所有 所有

shared_ptr<Y>

ポイント

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

04/12/2385

まとめ• C++ では所有が重要• shared_ptr は所有者が複数居る場合に

– 所有カウントで簡単・安全に動作– 動的デリータによる高い互換性を維持

• weak_ptr– 「生きているかどうか」を答えるプロキシ– shared_ptr に格上げして一時的に所有

• shared_ptr / weak_ptr で楽しい C++ ライフ