boost::weak_ptr

トップページ > メモリ管理 >

abstract

必要なヘッダ
<boost/weak_ptr.hpp>
出来ること
shared_ptrを横から覗き見
リファレンス
en / jp

sample

サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]

#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
using namespace std;
using namespace boost;

struct test {
	test(const char* name) : name_(name) {}
	~test() {cout << name_ << " destructed." << endl;}
	void showName() {cout << "Name: " << name_ << endl;}
	const char* name_;
};

int main()
{
	shared_ptr<test> sp( new test("ABC") );
	weak_ptr<test> wp( sp );

	// ポインタが有効なら処理を実行
	if( shared_ptr<test> tmp = wp.lock() )
		tmp->showName();
	else
		cout << "already deleted." << endl;

	// ここでdeleteされる
	sp.reset();

	// ポインタが有効なら処理を実行
	if( shared_ptr<test> tmp = wp.lock() )
		tmp->showName();
	else
		cout << "already deleted." << endl;
	return 0;
}

出力例

Name: ABC
ABC destructed.
already deleted.

etc

shared_ptr と共に使います。 shared_ptr とこちらとの違いは、weak_ptr は参照カウントを上げたり下げたりしないということ。 つまり、同じオブジェクトを指す weak_ptr が生きていたとしても、 shared_ptr が全て無くなった場合は(参照カウント0になるので) 対象オブジェクトは delete されてしまいます。

そういう使い方をする時は、shared_ptr::get() で普通のポインタを取っておいて使いまわせばよいではないか? との疑問が浮かびます。が、weak_ptr の場合、参照カウント 0 になったオブジェクトを利用しようとすると null を返して既に無効になったことを知らせてくれたり、 処理をする際に一時的に shared_ptr を作ることで、作業中に突然 delete されたりする事態を防ぐことができて便利です。

「オブジェクトを所有するわけではないので shared_ptr を使う場面ではないのだけれど、 対象オブジェクトが解放されたあともその変数で参照する可能性があるので、 そのときには解放されたことを検知したい」 という場面で使います。 Observer パターンで監視される側が通知相手を weak_ptr で覚えておく、 というのが一番典型的な使用例です。

see also

presented by k.inaba (kiki .a.t. kmonos.net) under CC0