84
2009/12/14 1 shared_ptr & weak_ptr くらいおらいと http://twitter.com/Cryolite/

shared_ptr & weak_ptr (pdf 第2版)

Embed Size (px)

DESCRIPTION

2009/12/12 Boost.勉強会 プレゼン資料 ppt 第2版. 初版の明らかな不手際を最低限だけ修正. プレゼン発表の録画は http://bit.ly/6yjSkz です.

Citation preview

Page 1: shared_ptr & weak_ptr (pdf 第2版)

2009/12/141

shared_ptr & weak_ptrくらいおらいと

http://twitter.com/Cryolite/

Page 2: shared_ptr & weak_ptr (pdf 第2版)

2009/12/142

キーワードは所有 (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 (pdf 第2版)

2009/12/143

所有とは…

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

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

Page 4: shared_ptr & weak_ptr (pdf 第2版)

2009/12/144

所有を制するものが

C++ を制する

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

=> Dangling pointer

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

=> Memory leak

Page 5: shared_ptr & weak_ptr (pdf 第2版)

2009/12/145

所有の種類と例

• 所有者がただ⼀⼈, 所有者変更不可• 配列とその要素• クラスオブジェクトとメンバ変数• 関数スコープ

(の実⾏) と⾃動変数

• プログラム

(の実⾏) と静的変数• 所有者がただ⼀⼈, 所有者変更可

• std::auto_ptr

• (ムーブセマンティクス)

• 共有

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

Page 6: shared_ptr & weak_ptr (pdf 第2版)

2009/12/146

共有は難しい

Page 7: shared_ptr & weak_ptr (pdf 第2版)

2009/12/147

共有は難しい

私が⽚付けましょう

Page 8: shared_ptr & weak_ptr (pdf 第2版)

2009/12/148

共有は難しい

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

Page 9: shared_ptr & weak_ptr (pdf 第2版)

2009/12/149

共有は難しい

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

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

Page 10: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1410

shared_ptr

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

1

共有されるもの

所有カウント

Page 11: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1411

shared_ptr

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

2

共有されるもの

所有カウント

Page 12: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1412

shared_ptr

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

3

共有されるもの

所有カウント

Page 13: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1413

shared_ptr

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

4

共有されるもの

所有カウント

Page 14: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1414

shared_ptr

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

4

共有されるもの

所有カウント所有カウントが0になったら

片づけを実行

Page 15: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1415

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

1

共有されるもの

所有カウント

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

O.K.

Page 16: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1416

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

0

共有されるもの

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

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

所有カウント

O.K.

Page 17: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1417

shared_ptr

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

4

共有されるもの

所有カウント

Page 18: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1418

shared_ptr

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

4

共有されるもの

所有カウント

shared_ptr shared_ptr shared_ptr shared_ptr

Page 19: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1419

shared_ptr

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

• ポインタとして動作する

shared_ptr C++ の生ポインタと同じように動作

• 所有の権利を保障する

shared_ptr ポインタとして指しているものは生きている

• 所有の義務を履行する

shared_ptr 所有カウントが0になったら関数オブジェクト

(デリータ) を実行

強いポインタ

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

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

delete だけじゃない

Page 20: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1420

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 (pdf 第2版)

2009/12/1421

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 (pdf 第2版)

2009/12/1422

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 (pdf 第2版)

2009/12/1423

shared_ptr

– int

と同程度にスレッド安全

4

共有されるもの

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

shared_ptr shared_ptr shared_ptr shared_ptr

Page 24: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1424

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

所有

所有

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

Page 25: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1425

発表終わり

Page 26: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1426

shared_ptr

の重要なデザインゴール

• ポインタと同等の型互換性

/ バイナリ互換性

• 非侵入性

– あなたのクラス定義に変更なし

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

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

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

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

Page 27: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1427

オレオレスマートポインタ

void processX(shared_ptr<X> px);

oreore_ptr<X> px(new

X(…));

processX(px); // コンパイルエラー

Page 28: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1428

オレオレスマートポインタ

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> >(px));

processX(qx); // O.K.

Page 29: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1429

オレオレスマートポインタ

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> >(px));

processX(qx);

「所有」は型に現れない

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

shared_ptr

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

ポイント2

ポイント1

Page 30: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1430

所有しない

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 (pdf 第2版)

2009/12/1431

所有しない

void processX(shared_ptr<X> px);

static X x; // 静的変数

Struct

NullDeleter

{

void operator()(void

*){}

};

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

processX(px);

shared_ptr

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

ポイント1

「所有」は型に現れない

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

ポイント2

Page 32: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1432

バイナリ境界を越える

– 生ポインタの場合

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 (pdf 第2版)

2009/12/1433

バイナリ境界を越える

– shared_ptr

の場合

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 (リリースビルド)

Page 34: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1434

バイナリ境界を越える

– shared_ptr

の場合

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 をここで設定

Page 35: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1435

バイナリ境界を越える

– shared_ptr

の場合

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 が呼び出される

Page 36: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1436

バイナリ境界を越える

– shared_ptr

の場合

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 が設定されていようが バイナリ互換性を維持

Page 37: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1437

所有だけの

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 (pdf 第2版)

2009/12/1438

shared_ptr<void> による遅延解放

// HeavyToDispose

は削除のコスト大

shared_ptr<HeavyToDispose> px(…);

…// ここで削除して処理が止まると困る…px.reset();

Page 39: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1439

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 (pdf 第2版)

2009/12/1440

weak_ptr

4, 2

共有されるもの

所有カウント

shared_ptr shared_ptr

shared_ptr shared_ptr

weak_ptr

weak_ptr

弱いカウント

Page 41: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1441

weak_ptr

0, 2

共有されるもの

所有カウント

shared_ptr shared_ptr

shared_ptr shared_ptr

weak_ptr

weak_ptr

弱いカウント

Page 42: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1442

weak_ptr

0, 2

共有されるもの

所有カウント

weak_ptr

weak_ptr

弱いカウント

所有カウントが0になったら

片づけを実行

Page 43: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1443

weak_ptr

0, 2所有カウント

weak_ptr

weak_ptr

弱いカウント

Page 44: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1444

weak_ptr

0, 0所有カウント

weak_ptr

weak_ptr

弱いカウント

Page 45: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1445

weak_ptr

0, 0

weak_ptr

weak_ptr

弱いカウントが0になったら

カウントオブジェクトを片付け

Page 46: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1446

weak_ptr

にできること

– その1

4, 2

共有されるもの

所有カウント

shared_ptr shared_ptr

shared_ptr shared_ptr

weak_ptr

weak_ptr

弱いカウント

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

weak_ptr::expired

== false

Page 47: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1447

weak_ptr

にできること

– その1

0, 2所有カウント

weak_ptr

weak_ptr

弱いカウント

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

weak_ptr::expired

== true

Page 48: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1448

weak_ptr

にできること

– その1

0, 2所有カウント

weak_ptr

weak_ptr

弱いカウント

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

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

Page 49: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1449

weak_ptr

にできること

– その2

1, 2

共有されるもの

所有カウント

shared_ptr

weak_ptr

weak_ptr

弱いカウント

対象が生きていたら,それを

所有する

shared_ptr

を作り出せる

Page 50: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1450

weak_ptr

にできること

– その2

2, 2

共有されるもの

所有カウント

shared_ptr

weak_ptr

weak_ptr

弱いカウント

shared_ptr

対象が生きていたら,それを

所有する

shared_ptr

を作り出せる

Page 51: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1451

weak_ptr

にできること

– その2

0, 2所有カウント

weak_ptr

weak_ptr

弱いカウント

対象が死んでいたら空の

shared_ptr

しか取り出せない

Page 52: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1452

weak_ptr

にできること

– その2

0, 2所有カウント

weak_ptr

weak_ptr

弱いカウント

shared_ptr

対象が死んでいたら空の

shared_ptr

しか取り出せない

Page 53: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1453

weak_ptr

にできることのまとめ

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

• 対象が生きていたら

shared_ptr

に格上げ可 能

Page 54: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1454

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 (pdf 第2版)

2009/12/1455

生ポインタから

shared_ptr

を取得したい

void Framework::onEvent(X

*p)

{

// *p を所有する

shared_ptr

を取りたい

}

Page 56: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1456

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 57: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1457

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 (pdf 第2版)

2009/12/1458

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 (pdf 第2版)

2009/12/1459

weak_ptr

の使い方

– this への

weak_ptr

struct

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 (pdf 第2版)

2009/12/1460

weak_ptr

の使い方

– this への

weak_ptr

struct

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 (pdf 第2版)

2009/12/1461

Observer (Publisher/Subscriber)

Page 62: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1462

Observer でよくある事故

Page 63: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1463

Observer でよくある事故

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

Page 64: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1464

安全な

Observer

• 死んだオブジェクトにイベントを通知しない

• イベント通知中に

subscriber を解放させない

Page 65: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1465

安全な

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 (pdf 第2版)

2009/12/1466

安全な

Observer

weak_ptr<void> wp…; // subscriber への

weak_ptr

if (shared_ptr<void> p = wp.lock()) {

// 生きているときだけ通知

+ call_back

中だけ所有

call_back();

}

Page 67: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1467

安全な

Observer

…ということが

Boost.Signal2 で出来ます

鍵は weak_ptr<void> & shared_ptr<void>

Page 68: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1468

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

a

b

c

share_ptr

share_ptr

share_ptr share_ptr

Page 69: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1469

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

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 (pdf 第2版)

2009/12/1470

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

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 (pdf 第2版)

2009/12/1471

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

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 (pdf 第2版)

2009/12/1472

策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 (pdf 第2版)

2009/12/1473

策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;

}

Page 74: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1474

策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 (pdf 第2版)

2009/12/1475

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

a

b

c

y1

y2

y3

share_ptr

share_ptr

share_ptr share_ptr

map<void *, Y>

Page 76: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1476

策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 (pdf 第2版)

2009/12/1477

策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 (pdf 第2版)

2009/12/1478

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

a

b

c

map<void *, Y>

y1

y2

y3

share_ptr

share_ptr

share_ptr share_ptr

c を所有する

shared_ptr

がなくなると…

c をキーとするエントリも自動で

erase

Page 79: shared_ptr & weak_ptr (pdf 第2版)

2009/12/1479

循環所有を何とかする

// こういうことがしたい

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 (pdf 第2版)

2009/12/1480

循環所有を何とかする

// こういうことがしたい

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 (pdf 第2版)

2009/12/1481

循環所有を何とかする

// こういうことがしたい

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 (pdf 第2版)

2009/12/1482

循環所有を何とかする

// こういうことがしたい

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 (pdf 第2版)

2009/12/1483

循環所有を何とかする

// こういうことがしたい

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 (pdf 第2版)

2009/12/1484

まとめ

• C++ では所有が重要

• shared_ptr

は所有者が複数居る場合に– 所有カウントで簡単・安全に動作

– 動的デリータによる高い互換性を維持

• weak_ptr– 「生きているかどうか」を答えるプロキシ

– shared_ptr

に格上げして一時的に所有

• shared_ptr

/ weak_ptr

で楽しい

C++ ライフ